, :
: , 180- .
. ...
, . , . , .
, MKMapRect , :
NSString* MyStringCoordsFromMapRect(MKMapRect rect) {
MKMapPoint pNE = rect.origin, pSW = rect.origin;
pNE.x += rect.size.width;
pSW.y += rect.size.height;
CLLocationCoordinate2D sw, ne;
sw = MKCoordinateForMapPoint(pSW);
ne = MKCoordinateForMapPoint(pNE);
return [NSString stringWithFormat:@"{{%f, %f}, {%f, %f}}",
sw.latitude, sw.longitude, ne.latitude, ne.longitude];
}
/*
,
MapRect Spanning 180- :
*/
- (void)testHowToCreateMapRectSpanning180thMeridian
{
/*
location viewport , API Google, antimeridian. - - (-180,0):
*/
CLLocationCoordinate2D sw, ne, nw, se;
sw = CLLocationCoordinate2DMake(-12.9403000, 25.0159000);
ne = CLLocationCoordinate2DMake(81.6691780, -168.3545000);
nw = CLLocationCoordinate2DMake(ne.latitude, sw.longitude);
se = CLLocationCoordinate2DMake(sw.latitude, ne.longitude);
/*
, 268 , MKMapPoints. , , , ± 85 . -180 180 .
*/
NSLog(@"\nMKMapRectWorld: %@\n => %@",
MKStringFromMapRect(MKMapRectWorld),
MyStringCoordsFromMapRect(MKMapRectWorld));
/*
MKPolygon, , ?
*/
CLLocationCoordinate2D coords[] = {nw, ne, se, sw};
MKPolygon *p = [MKPolygon polygonWithCoordinates:coords count:4];
MKMapRect rp = p.boundingMapRect;
STAssertFalse(MKMapRectSpans180thMeridian(rp), nil);
NSLog(@"\n rp: %@\n => %@",
MKStringFromMapRect(rp),
MyStringCoordsFromMapRect(rp));
/*
, . {{-12, 25}, {81, -168}}. MKMapRect MKMapRectSpans180thMeridian, , !
, MKPolygon MKMapRect, . , . , , NE SW, ?
... - MKMapRectUnion. MKMapRect , , :
*/
MKMapPoint pNE = MKMapPointForCoordinate(ne);
MKMapPoint pSW = MKMapPointForCoordinate(sw);
MKMapRect ru = MKMapRectUnion(MKMapRectMake(pNE.x, pNE.y, 0, 0),
MKMapRectMake(pSW.x, pSW.y, 0, 0));
STAssertFalse(MKMapRectSpans180thMeridian(ru), nil);
STAssertEquals(ru, rp, nil);
NSLog(@"\n ru: %@\n => %@",
MKStringFromMapRect(ru),
MyStringCoordsFromMapRect(ru));
/*
, , . , MKPolygon , , MKRectUnion.
. , MapRect , .
*/
MKMapRect ra = MKMapRectMake(MIN(pNE.x, pSW.x), MIN(pNE.y, pSW.y),
ABS(pNE.x - pSW.x), ABS(pNE.y - pSW.y));
STAssertFalse(MKMapRectSpans180thMeridian(ru), nil);
STAssertEquals(ra, ru, nil);
NSLog(@"\n ra: %@\n => %@",
MKStringFromMapRect(ra),
MyStringCoordsFromMapRect(ra));
/*
! , . , , . , MKMapRectUnion. ...
*/
MKMapRect rb = MKMapRectMake(pSW.x, pNE.y,
(pNE.x - pSW.x), (pSW.y - pNE.y));
STAssertFalse(MKMapRectSpans180thMeridian(rb), nil);
NSLog(@"\n rb: %@\n => %@",
MKStringFromMapRect(rb),
MyStringCoordsFromMapRect(rb));
/*
, {{-12, 25}, {81, -168}}. , MKMapRect MKMapRectSpans180thMeridian. ...?!
MKOverlay.h :
, 180- , boundingMapRect MinX, MaxX, , MKMapSizeWorld.width.
. , rb.size.width 144 . .
, :
*/
double antimeridianOveflow =
(ne.longitude > sw.longitude) ? 0 : MKMapSizeWorld.width;
MKMapRect rc = MKMapRectMake(pSW.x, pNE.y,
(pNE.x - pSW.x) + antimeridianOveflow,
(pSW.y - pNE.y));
STAssertTrue(MKMapRectSpans180thMeridian(rc), nil);
NSLog(@"\n rc: %@\n => %@",
MKStringFromMapRect(rc),
MyStringCoordsFromMapRect(rc));
/*
, MKMapRectSpans180thMeridian. . ? - 191.6455. (-360), -168.3545. Q.E.D.
MKMapRect, 180- , : MaxX (rc.origin.x + rc.size.width= 152870935.0 + 124248035.2 = 277118970.2) ( 268 ).
, MinX === origin.x?
*/
MKMapRect rd = MKMapRectMake(pSW.x - antimeridianOveflow, pNE.y,
(pNE.x - pSW.x) + antimeridianOveflow,
(pSW.y - pNE.y));
STAssertTrue(MKMapRectSpans180thMeridian(rd), nil);
NSLog(@"\n rd: %@\n => %@",
MKStringFromMapRect(rd),
MyStringCoordsFromMapRect(rd));
STAssertFalse(MKMapRectEqualToRect(rc, rd), nil);
/*
MKMapRectSpans180thMeridian. , - : -334.9841. (+360), 25.0159. Q.E.D.
, MKMapRect, 180- . .
, (rd), , , :
*/
MKMapPoint points[4];
if (nw.longitude > ne.longitude) {
points[0] = MKMapPointForCoordinate(
CLLocationCoordinate2DMake(nw.latitude, -nw.longitude));
points[0].x = - points[0].x;
}
else
points[0] = MKMapPointForCoordinate(nw);
points[1] = MKMapPointForCoordinate(ne);
points[2] = MKMapPointForCoordinate(se);
points[3] = MKMapPointForCoordinate(sw);
points[3].x = points[0].x;
MKPolygon *p2 = [MKPolygon polygonWithPoints:points count:4];
MKMapRect rp2 = p2.boundingMapRect;
STAssertTrue(MKMapRectSpans180thMeridian(rp2), nil);
NSLog(@"\n rp2: %@\n => %@",
MKStringFromMapRect(rp2),
MyStringCoordsFromMapRect(rp2));
/*
, MKMapPoint , MKPolygon boundingMapRect. rect (rd).
*/
STAssertTrue([MKStringFromMapRect(rp2) isEqualToString:
MKStringFromMapRect(rd)], nil);
/*
... , :
*/
/*
, , , ...
*/
}
.
, MKPolygon . , MKMapRect, , - . , , . , , 180- . MKPolygonView 180- . .
rect:
- (MKPolygon *)polygonFor:(MKMapRect)r
{
MKMapPoint p1 = r.origin, p2 = r.origin, p3 = r.origin, p4 = r.origin;
p2.x += r.size.width;
p3.x += r.size.width; p3.y += r.size.height;
p4.y += r.size.height;
MKMapPoint points[] = {p1, p2, p3, p4};
return [MKPolygon polygonWithPoints:points count:4];
}
.
for (GGeocodeResult *location in locations) {
MKMapRect r = location.mapRect;
[self.debugLocationBounds addObject:[self polygonFor:r]];
if (MKMapRectSpans180thMeridian(r)) {
r.origin.x -= MKMapSizeWorld.width;
[self.debugLocationBounds addObject:[self polygonFor:r]];
}
}
[self.mapView addOverlays:self.debugLocationBounds];
, , 180- .