Authored by Vladimir Vyskocil

Merge of the Luca's patch modified by Ivo Brodien from the route-me mailling-lis…

…t. Fix problems with path overlay layer diseappearing (size > 1024 pixels)
... ... @@ -130,23 +130,26 @@
- (CGPoint) projectXYPoint:(RMProjectedPoint)aPoint withMetersPerPixel:(float)aScale
{
CGPoint aPixelPoint;
CGFloat originX = origin.easting;
CGFloat boundsWidth = [projection planetBounds].size.width;
CGFloat pointX = aPoint.easting - boundsWidth/2;
CGFloat left = sqrt((pointX - (originX - boundsWidth))*(pointX - (originX - boundsWidth)));
CGFloat middle = sqrt((pointX - originX)*(pointX - originX));
CGFloat right = sqrt((pointX - (originX + boundsWidth))*(pointX - (originX + boundsWidth)));
if(middle <= left && middle <= right){
aPixelPoint.x = (aPoint.easting - originX) / aScale;
} else if(left <= middle && left <= right){
aPixelPoint.x = (aPoint.easting - (originX-boundsWidth)) / aScale;
} else{ //right
aPixelPoint.x = (aPoint.easting - (originX+boundsWidth)) / aScale;
}
CGFloat originX = origin.easting;
CGFloat boundsWidth = [projection planetBounds].size.width;
CGFloat pointX = aPoint.easting - boundsWidth/2;
CGFloat left = sqrt((pointX - (originX - boundsWidth))*(pointX - (originX - boundsWidth)));
CGFloat middle = sqrt((pointX - originX)*(pointX - originX));
CGFloat right = sqrt((pointX - (originX + boundsWidth))*(pointX - (originX + boundsWidth)));
//RMLog(@"left:%f middle:%f right:%f x:%f width:%f", left, middle, right, pointX, boundsWidth);//LK
if(middle <= left && middle <= right){
aPixelPoint.x = (aPoint.easting - originX) / aScale;
} else if(left <= middle && left <= right){
//RMLog(@"warning: projectXYPoint middle..");//LK
aPixelPoint.x = (aPoint.easting - (originX/*-boundsWidth*/)) / aScale;
} else{ //right
aPixelPoint.x = (aPoint.easting - (originX+boundsWidth)) / aScale;
}
aPixelPoint.y = screenBounds.size.height - (aPoint.northing - origin.northing) / aScale;
return aPixelPoint;
return aPixelPoint;
}
- (CGPoint) projectXYPoint: (RMProjectedPoint)aPoint
... ...
... ... @@ -24,7 +24,7 @@
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
#import "RMGlobalConstants.h"
#import "RMPath.h"
#import "RMMapView.h"
#import "RMMapContents.h"
... ... @@ -52,11 +52,11 @@
drawingMode = kCGPathFillStroke;
lineColor = [UIColor blackColor];
fillColor = [UIColor redColor];
self.masksToBounds = NO;
scaleLineWidth = YES;
// self.frame = CGRectMake(100, 100, 100, 100);
// [self setNeedsDisplayOnBoundsChange:YES];
//self.masksToBounds = NO;
self.masksToBounds = YES;
scaleLineWidth = NO;
return self;
}
... ... @@ -81,42 +81,74 @@
}
- (void) recalculateGeometry
{
{
float scale = [[contents mercatorToScreenProjection] metersPerPixel];
float scaledLineWidth;
CGPoint myPosition;
CGRect pixelBounds, screenBounds;
float offset;
const float outset = 100.0f; // provides a buffer off screen edges for when path is scaled or moved
float scaledLineWidth = lineWidth;
// The bounds are actually in mercators...
/// \bug if "bounds are actually in mercators", shouldn't be using a CGRect
scaledLineWidth = lineWidth;
if(!scaleLineWidth) {
renderedScale = [contents metersPerPixel];
scaledLineWidth *= renderedScale;
}
// The bounds are actually in mercators...
/// \bug if "bounds are actually in mercators", shouldn't be using a CGRect
CGRect boundsInMercators = CGPathGetBoundingBox(path);
boundsInMercators.origin.x -= scaledLineWidth;
boundsInMercators.origin.y -= scaledLineWidth;
boundsInMercators.size.width += 2*scaledLineWidth;
boundsInMercators.size.height += 2*scaledLineWidth;
CGRect pixelBounds = RMScaleCGRectAboutPoint(boundsInMercators, 1.0f / scale, CGPointZero);
// RMLog(@"old bounds: %f %f %f %f", self.bounds.origin.x, self.bounds.origin.y, self.bounds.size.width, self.bounds.size.height);
pixelBounds = CGRectInset(boundsInMercators, -scaledLineWidth, -scaledLineWidth);
pixelBounds = RMScaleCGRectAboutPoint(pixelBounds, 1.0f / scale, CGPointZero);
// Clip bound rect to screen bounds.
// If bounds are not clipped, they won't display when you zoom in too much.
myPosition = [[contents mercatorToScreenProjection] projectXYPoint: origin];
screenBounds = [contents screenBounds];
// Clip top
offset = myPosition.y + pixelBounds.origin.y - screenBounds.origin.y + outset;
if(offset < 0.0f) {
pixelBounds.origin.y -= offset;
pixelBounds.size.height += offset;
}
// Clip left
offset = myPosition.x + pixelBounds.origin.x - screenBounds.origin.x + outset;
if(offset < 0.0f) {
pixelBounds.origin.x -= offset;
pixelBounds.size.width += offset;
}
// Clip bottom
offset = myPosition.y + pixelBounds.origin.y + pixelBounds.size.height - screenBounds.origin.y - screenBounds.size.height - outset;
if(offset > 0.0f) {
pixelBounds.size.height -= offset;
}
// Clip right
offset = myPosition.x + pixelBounds.origin.x + pixelBounds.size.width - screenBounds.origin.x - screenBounds.size.width - outset;
if(offset > 0.0f) {
pixelBounds.size.width -= offset;
}
self.position = myPosition;
self.bounds = pixelBounds;
// RMLog(@"new bounds: %f %f %f %f", self.bounds.origin.x, self.bounds.origin.y, self.bounds.size.width, self.bounds.size.height);
//RMLog(@"x:%f y:%f screen bounds: %f %f %f %f", myPosition.x, myPosition.y, screenBounds.origin.x, screenBounds.origin.y, screenBounds.size.width, screenBounds.size.height);
//RMLog(@"new bounds: %f %f %f %f", self.bounds.origin.x, self.bounds.origin.y, self.bounds.size.width, self.bounds.size.height);
// RMLog(@"old position: %f %f", self.position.x, self.position.y);
self.position = [[contents mercatorToScreenProjection] projectXYPoint: origin];
// RMLog(@"new position: %f %f", self.position.x, self.position.y);
// RMLog(@"Old anchor point %f %f", self.anchorPoint.x, self.anchorPoint.y);
self.anchorPoint = CGPointMake(-pixelBounds.origin.x / pixelBounds.size.width,-pixelBounds.origin.y / pixelBounds.size.height);
// RMLog(@"new anchor point %f %f", self.anchorPoint.x, self.anchorPoint.y);
[self setNeedsDisplay];
}
- (void) addPointToXY: (RMProjectedPoint) point withDrawing: (BOOL)isDrawing
{
// RMLog(@"addLineToXY %f %f", point.easting, point.northing);
// RMLog(@"addLineToXY %f %f", point.x, point.y);
NSValue* value = [NSValue value:&point withObjCType:@encode(RMProjectedPoint)];
if (points == nil)
... ... @@ -124,24 +156,25 @@
points = [[NSMutableArray alloc] init];
[points addObject:value];
origin = point;
self.position = [[contents mercatorToScreenProjection] projectXYPoint: origin];
// RMLog(@"screen position set to %f %f", self.position.x, self.position.y);
// RMLog(@"screen position set to %f %f", self.position.x, self.position.y);
CGPathMoveToPoint(path, NULL, 0.0f, 0.0f);
}
else
{
[points addObject:value];
point.easting = point.easting - origin.easting;
point.northing = point.northing - origin.northing;
if (isDrawing)
{
CGPathAddLineToPoint(path, NULL, point.easting, -point.northing);
} else {
CGPathMoveToPoint(path, NULL, point.easting, -point.northing);
}
[self recalculateGeometry];
}
[self setNeedsDisplay];
... ... @@ -195,11 +228,12 @@
if(!scaleLineWidth) {
scaledLineWidth *= renderedScale;
}
//NSLog(@"line width = %f, content scale = %f", scaledLineWidth, renderedScale);
CGContextScaleCTM(theContext, scale, scale);
CGContextBeginPath(theContext);
CGContextAddPath(theContext, path);
CGContextAddPath(theContext, path);
CGContextSetLineWidth(theContext, scaledLineWidth);
CGContextSetStrokeColorWithColor(theContext, [lineColor CGColor]);
... ... @@ -254,7 +288,6 @@
{
return fillColor;
}
- (void)setFillColor:(UIColor *)aFillColor
{
if (fillColor != aFillColor) {
... ... @@ -264,18 +297,23 @@
}
}
- (void)moveBy: (CGSize) delta {
[super moveBy:delta];
[self recalculateGeometry];
}
- (void)zoomByFactor: (float) zoomFactor near:(CGPoint) pivot
{
[super zoomByFactor:zoomFactor near:pivot];
// don't redraw if the path hasn't been scaled very much
float newMPP = [contents metersPerPixel];
if (newMPP / renderedScale >= 2.0f
|| newMPP / renderedScale <= 0.5f)
float newScale = [contents metersPerPixel];
if (newScale / renderedScale >= 1.10f
|| newScale / renderedScale <= 0.90f)
{
[self recalculateGeometry];
[self setNeedsDisplay];
}
}
@end
... ...