UIView坐标系 - 偏移和翻译

时间:2011-06-11 22:59:09

标签: objective-c uiview translation coordinates coordinate-systems

我很确定这更像是一个数学问题,但我会在UIView和iPad相关的目标C的背景下对它进行说明

我从我从其他地方下载的一些公共域材料创建的映射文件中导入原始数据,然后拆分以隔离地图中的各个区域。每个地区都有许多子区域,很像是美国大陆,然后是美国境内出现的各个州,然后每个子区域再次被分解,进入,比如说,县。

每个州,每个县都有一个边界框,告诉我每个州的起源,宽度和高度。

在我的初始设置中,我为每个州创建了一个单独的视图,然后为每个县创建了另一个视图。表示状态/县的区域的多边形相对于我通过界面构建​​器创建的视图(称为mainContainerView)呈现(显然,县位于状态顶部以便​​可见)。这个初始设置正常工作。

现在我试图通过将状态添加到保持状态多边形的UIView中来改变一些事情,因此我将能够将状态覆盖为县的剪贴蒙版。问题在于,无论我尝试什么,我似乎都无法将县转移到州内的正确位置。

似乎它应该是直接的加法或减法,因为每个项目的缩放完全相同,而且我不会尝试进行任何重大转换,因此我不相信CFAffineTransformation系列是必需的。

我可以在必要时发布代码,但我不是想让别人为我编写程序;我只是希望有人在这里指出我正确的方向,给我一个关于如何在州内观点设置县相对于州的建议。

根据请求,这是我正在处理的相关代码。这段代码不起作用,但它可以让你了解我在做什么。发布样本数据有点困难,因为它涉及从设计用于生成地图(和细分)的.SHP文件中提取的点数组和数据。当我逐步完成程序向你展示他们正在发生什么时,我会在代码中包含一些注释和一些真正的值。

MASK_MAX_EASTING,MASK_MAX_NORTHING,MASK_MIN_EASTING和MASK_MIN_NORTHING是常量,用于定义由国家/地区组成的国家/地区的整个地图的边界框。

DIST_MAX_EASTING,DIST_MAX_NORTHING,DIST_MIN_EASTING和DIST_MIN_NORTHING是常量,用于定义由郡组成的国家/地区的地图的边界框。两个地图的比例略有不同,因此,通过使用不同的边界框,我已经能够将两个地图缩放到相同的大小。

-(void)didLoadMap:(NSNotification *)notification {

id region = [notification object];
ShapePolyline *polygon = [region polygon];

if ([notification name] == @"MapsLoadingForState") {

    // m_nBoundingBox is an array which contains the RAW northing and easting values for each subdivision.  [0] - west limit, [1] - south limit, [2] - east limit, [3] - north limit.

    // The code below, combined with the drawrect method in DrawMap.m (below) puts all the states on the map in precisely the right places, so for the state maps, it works just fine.

    CGFloat originX = ((polygon->m_nBoundingBox[0]-MASK_MIN_EASTING)*stateScaleMultiplier)+([mainContainerView frame].size.width/2);

    CGFloat originY = ((MASK_MAX_NORTHING-(polygon->m_nBoundingBox[3]))*stateScaleMultiplier)+[mainContainerView frame].origin.y;  
    CGFloat width = polygon->m_nBoundingBox[2] - polygon->m_nBoundingBox[0];
    CGFloat height = polygon->m_nBoundingBox[3] - polygon->m_nBoundingBox[1];

    CGFloat scaledWidth = width*stateScaleMultiplier;
    CGFloat scaledHeight = height*stateScaleMultiplier;
    UIColor *subViewColor = [UIColor colorWithRed:0.0 green:1.0 blue:1.0 alpha:0.0];

    stateMapView = [[DrawMap alloc] initWithFrame:CGRectMake(originX, originY, scaledWidth, scaledHeight)];
    [stateMapView setBackgroundColor:subViewColor];

    [stateMapView setStateScale:stateScaleMultiplier];
    [stateMapView setCountyScale:countyScaleMultiplier];  // Not actually needed.

    [stateMapView setClippingMask:polygon];
    UIColor *colorMask = [UIColor colorWithWhite:1.0 alpha:1.0];
    [stateMapView setForeground:colorMask];

    [states addObject:stateMapView];                      // Add the state map view to an array (for future use)
    [mapView addSubview:stateMapView];  // MapView is a UIView of equivalent size and shape as mainContainerView.

} else {

    // This is where the problems occur.  

    CGFloat originX = (polygon->m_nBoundingBox[0]-DIST_MIN_EASTING);  // 4431590 (raw data)
    originX *= countyScaleMultiplier;  // 303.929108
    originX += ([mainContainerView frame].size.width/2);  // 815.929077

    CGFloat originY = (DIST_MAX_NORTHING-polygon->m_nBoundingBox[3]); 4328997 
    originY *= countyScaleMultiplier;  // 296.893036
    originY -= [mainContainerView frame].origin.y;  // 340.893036

    CGRect frame = [stateMapView frame];  // Dummy variable created for watches in the debugger.  x=856.237183, y=332.169922 width=34.3800087, height=28.7534008

    // When I was invoking DrawMap.h and the included drawrect method, the county map would easily be displayed in the right place, as you can see by the values above.

    // This is where I think the problem is.  The X value is WAY off as far as I can tell.
    originX -= frame.origin.x; // -40.3081055 
    originY -= frame.origin.y; // 8.72311401

    CGPoint countyOrigin = CGPointMake(originX,originY);

    // Translate the county's origin so it is relative to the origin of stateMapView, not MainContainerView (doesn't work)

    [stateMapView addCountyMap:[region polygon] withColor:winner translatedBy:countyOrigin];
    [stateMapView setNeedsDisplay];
}

我知道这个代码有几个问题,这个问题范围之外的一些东西可能会让你们中的一些人眉毛(或两个),但这绝对是一项正在进行的工作......

这是DrawMap.m的相关代码;我已经把一堆东西剪掉了,因为它是无关紧要的。

- (void)drawRect:(CGRect)rect {

// Set up

for (int i=0;i<[countyMaps count];i++) {

    // Draw the polygon.

    [[countyColors objectAtIndex:i] setFill];

    [self drawPolygon:[countyMaps objectAtIndex:i]
           usingScale:stateScale
         translatedBy:CGPointMake([[countyTranslations objectAtIndex:2*i] floatValue],
                                  [[countyTranslations objectAtIndex:2*i+1] floatValue])]; 

}

// Set the blend mode to multiply

CGContextSetBlendMode(context, kCGBlendModeMultiply);

// Draw a path with clippingMask

[[UIColor colorWithWhite:1.0 alpha:1.0] setFill];
// CGPoint translate = CGPointMake(0,0);

[self drawPolygon:clippingMask usingScale:stateScale translatedBy:CGPointMake(0,0)];

}

-(void)drawPolygon:(ShapePolyline *)aPolygon usingScale:(float)mapScale translatedBy:(CGPoint)trans {

for (int j=0;j<[aPolygon numParts];j++) {

    UIBezierPath *path = [UIBezierPath bezierPath];

    [path setLineJoinStyle:kCGLineJoinRound];

    int startIndex = [[[aPolygon m_Parts] objectAtIndex:j] intValue];
    int endIndex = [aPolygon numPoints];

    CGPoint startPoint;
    [[[aPolygon m_Points] objectAtIndex:startIndex] getValue:&startPoint];

    startPoint.x *=mapScale;
    startPoint.y *=mapScale;

    startPoint.x -= trans.x;
    startPoint.y -= trans.y;

    [path moveToPoint:startPoint];


    if (j+1 != [aPolygon numParts]){ 

        endIndex = [[[aPolygon m_Parts] objectAtIndex:j+1] intValue];
    }

    for (int k=startIndex+1; k<endIndex; k++)
    {
        CGPoint nextPoint;
        [[[aPolygon m_Points] objectAtIndex:k] getValue:&nextPoint];

        nextPoint.x *= mapScale;
        nextPoint.y *= mapScale;

        nextPoint.x -= trans.x;
        nextPoint.y -= trans.y;

        [path addLineToPoint:nextPoint];

    }
    [path closePath];
    // [path stroke];
    [path fill];
}

}

这本书真的可能是太多的信息,或者它可能还不够。无论哪种方式,希望通过添加代码,我已经给你一些信息继续......

1 个答案:

答案 0 :(得分:1)

-SOLVED -

这很简单。我很惊讶我花了很长时间才弄清楚,因为我在最初的问题中是对的 - 这是简单的加法和减法:

所有翻译现在都在渲染多边形的方法内完成。对于多边形中的每个点,我需要添加状态视图的原点,并减去县边界框的原点,然后从Y值(控制条的高度)中减去44。

我认为,这是一个过度思考问题,变得沮丧,过度思考,只是在三天之后发现答案正在盯着你,挥舞着红旗,大喊大叫的例子。 ,“我在这儿!!!!”