Системы координат UIView - смещение и перевод - PullRequest
3 голосов
/ 12 июня 2011

Я почти уверен, что это скорее математический вопрос, но я сформулирую его в контексте задачи, связанной с UIView и iPad. C

Я импортирую необработанные данные из файла сопоставления. Iбыли созданы из общедоступного материала, загруженного в другом месте, а затем разделены, чтобы изолировать различные регионы на карте.В каждом регионе есть несколько субрегионов, как, например, континентальная часть США, а затем различные штаты, которые появляются в пределах США, а затем каждый субрегион снова разбивается на, скажем, округа.

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

В моей первоначальной настройке я создал отдельное представление для каждого штата, а затем другое представление для каждого округа.Многоугольник, представляющий область штата / округа, был визуализирован (очевидно, с округом в верхней части штата, чтобы он был видимым) относительно представления, созданного мной через конструктор интерфейса, называемого 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.м;Я вырезал кучу вещей, потому что они посторонние.

- (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 Ответ

1 голос
/ 13 июня 2011

-SOLVED-

И это было так просто.Я удивлен, что мне понадобилось так много времени, чтобы понять это, поскольку я был прав в своем первоначальном вопросе - это было простое сложение и вычитание:

Все переводы теперь выполняются внутри методов, которые визуализируют многоугольники.Для каждой точки в многоугольнике мне нужно было добавить начало представления государства и вычесть начало ограничительной рамки округа, затем вычесть 44 из значения Y (высота панели управления).

Это, я думаю, пример чрезмерного обдумывания проблемы, разочарования, чрезмерного обдумывания, и только через три дня выясняется, что ответ смотрит вам в лицо, размахивая красным флагом.и выкрикивая: «Я ЗДЕСЬ ЗДЕСЬ !!!!»

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...