Алгоритм для определения минимального ограничительного прямоугольника для набора координат широты/долготы

У меня есть две функции:

function setSelectionRange(input, selectionStart, selectionEnd) {
  if (input.setSelectionRange) {
    input.focus();
    input.setSelectionRange(selectionStart, selectionEnd);
  }
  else if (input.createTextRange) {
    var range = input.createTextRange();
    range.collapse(true);
    range.moveEnd('character', selectionEnd);
    range.moveStart('character', selectionStart);
    range.select();
  }
}

function setCaretToPos (input, pos) {
  setSelectionRange(input, pos, pos);
}

Затем можно использовать setCaretToPos как это:

setCaretToPos(document.getElementById("YOURINPUT"), 4);

Живой пример и с textarea и с input, показывая использование из jQuery:

function setSelectionRange(input, selectionStart, selectionEnd) {
  if (input.setSelectionRange) {
    input.focus();
    input.setSelectionRange(selectionStart, selectionEnd);
  } else if (input.createTextRange) {
    var range = input.createTextRange();
    range.collapse(true);
    range.moveEnd('character', selectionEnd);
    range.moveStart('character', selectionStart);
    range.select();
  }
}

function setCaretToPos(input, pos) {
  setSelectionRange(input, pos, pos);
}

$("#set-textarea").click(function() {
  setCaretToPos($("#the-textarea")[0], 10)
});
$("#set-input").click(function() {
  setCaretToPos($("#the-input")[0], 10);
});




По состоянию на 2016, протестированный и работающий над Chrome, Firefox, IE11, даже IE8 (см. что в последний раз здесь ; Отрывки Стека не поддерживают IE8).

15
задан Peter Mortensen 23 November 2010 в 13:37
поделиться

5 ответов

Чтобы проверить, является ли объект o строковым типом подкласса строкового типа:

isinstance(o, basestring)

, потому что оба str и unicode является подклассом basestring .

Чтобы проверить, является ли тип o в точности str :

type(o) is str

Чтобы проверить, является ли o является экземпляром str или любого подкласса str :

isinstance(o, str)

Вышеупомянутое также работает для строк Unicode, если вы замените str на ] unicode .

Однако вам может вообще не понадобиться выполнять явную проверку типов. "Утиный ввод" может соответствовать вашим потребностям. См. http://docs.python.org/glossary.html#term-duck-typing . и наибольшая широта / долгота для вашей нижней правой точки.

double minLat = 900;
double minLon = 900;
double maxLat = -900;
double maxLon = -900;
foreach(Point point in latloncollection )
{
    minLat = Math.min( minLat, point.lat );
    minLon = Math.min( minLon, point.lon );
    maxLat = Math.max( maxLat, point.lat );
    maxLon = Math.max( maxLon, point.lon );
}
11
ответ дан 1 December 2019 в 02:46
поделиться

Для того, что вы хотите сделать, вы могли бы просто найти минимальное и максимальное значения для широты и долготы и использовать их как границы вашего прямоугольника. Для более сложных решений см .:

Вычислить прямоугольник с минимальной площадью для многоугольника

0
ответ дан 1 December 2019 в 02:46
поделиться

Все, что вам нужно сделать, это получить крайнее левое, самое верхнее, крайнее правое и самое нижнее значения. Вы можете легко добиться этого путем сортировки, и пока набор не слишком велик, это будет не очень дорого.

Если вы дадите своим методам класса широты / долготы, называемым compareLatitude: и compareLongitude: , было бы еще проще.

CGFloat north, west, east, south;  
[latLongCollection sortUsingSelector:@selector(compareLongitude:)];  
west = [[latLongCollection objectAtIndex:0] longitude];  
east = [[latLongCollection lastObject] longitude];  
[latLongCollection sortUsingSelector:@selector(compareLatitude:)];  
south = [[latLongCollection objectAtIndex:0] latitude];  
north = [[latLongCollection lastObject] latitude];

Что-то вроде этого должно работать, если ваша коллекция координат представляет собой NSMutableArray.

0
ответ дан 1 December 2019 в 02:46
поделиться

Если вы используете Objective-C, вы могли бы использовать вместо него Objective-C ++, и в этом случае вы можете использовать STL, чтобы сделать за вас большую часть тяжелой работы:

#include <vector>
#include <algorithm>

std::vector<float> latitude_set;
std::vector<float> longitude_set;

latitude_set.push_back(latitude_a);
latitude_set.push_back(latitude_b);
latitude_set.push_back(latitude_c);
latitude_set.push_back(latitude_d);
latitude_set.push_back(latitude_e);

longitude_set.push_back(longitude_a);
longitude_set.push_back(longitude_b);
longitude_set.push_back(longitude_c);
longitude_set.push_back(longitude_d);
longitude_set.push_back(longitude_e);

float min_latitude = *std::min_element(latitude_set.begin(), latitude_set.end());
float max_latitude = *std::max_element(latitude_set.begin(), latitude_set.end());

float min_longitude = *std::min_element(longitude_set.begin(), longitude_set.end());
float max_longitude = *std::max_element(longitude_set.begin(), longitude_set.end());
0
ответ дан 1 December 2019 в 02:46
поделиться

Это метод, который я использую в одном из моих приложений.

- (void)centerMapAroundAnnotations
{
    // if we have no annotations we can skip all of this
    if ( [[myMapView annotations] count] == 0 )
        return;

    // then run through each annotation in the list to find the
    // minimum and maximum latitude and longitude values
    CLLocationCoordinate2D min;
    CLLocationCoordinate2D max; 
    BOOL minMaxInitialized = NO;
    NSUInteger numberOfValidAnnotations = 0;

    for ( id<MKAnnotation> a in [myMapView annotations] )
    {
        // only use annotations that are of our own custom type
        // in the event that the user is browsing from a location far away
        // you can omit this if you want the user's location to be included in the region 
        if ( [a isKindOfClass: [ECAnnotation class]] )
        {
            // if we haven't grabbed the first good value, do so now
            if ( !minMaxInitialized )
            {
                min = a.coordinate;
                max = a.coordinate;
                minMaxInitialized = YES;
            }
            else // otherwise compare with the current value
            {
                min.latitude = MIN( min.latitude, a.coordinate.latitude );
                min.longitude = MIN( min.longitude, a.coordinate.longitude );

                max.latitude = MAX( max.latitude, a.coordinate.latitude );
                max.longitude = MAX( max.longitude, a.coordinate.longitude );
            }
            ++numberOfValidAnnotations;
        }
    }

    // If we don't have any valid annotations we can leave now,
    // this will happen in the event that there is only the user location
    if ( numberOfValidAnnotations == 0 )
        return;

    // Now that we have a min and max lat/lon create locations for the
    // three points in a right triangle
    CLLocation* locSouthWest = [[CLLocation alloc] 
                                initWithLatitude: min.latitude 
                                longitude: min.longitude];
    CLLocation* locSouthEast = [[CLLocation alloc] 
                                initWithLatitude: min.latitude 
                                longitude: max.longitude];
    CLLocation* locNorthEast = [[CLLocation alloc] 
                                initWithLatitude: max.latitude 
                                longitude: max.longitude];

    // Create a region centered at the midpoint of our hypotenuse
    CLLocationCoordinate2D regionCenter;
    regionCenter.latitude = (min.latitude + max.latitude) / 2.0;
    regionCenter.longitude = (min.longitude + max.longitude) / 2.0;

    // Use the locations that we just created to calculate the distance
    // between each of the points in meters.
    CLLocationDistance latMeters = [locSouthEast getDistanceFrom: locNorthEast];
    CLLocationDistance lonMeters = [locSouthEast getDistanceFrom: locSouthWest];

    MKCoordinateRegion region;
    region = MKCoordinateRegionMakeWithDistance( regionCenter, latMeters, lonMeters );

    MKCoordinateRegion fitRegion = [myMapView regionThatFits: region];
    [myMapView setRegion: fitRegion animated: YES];

    // Clean up
    [locSouthWest release];
    [locSouthEast release];
    [locNorthEast release];
}
10
ответ дан 1 December 2019 в 02:46
поделиться