3

これは数学の質問であると確信していますが、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 は、郡で構成される国の地図の境界ボックスを定義する定数です。2 つのマップの縮尺はわずかに異なるため、異なる境界ボックスを使用することで、2 つのマップを同じサイズに縮尺することができました。

-(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];
}

}

この本は本当に情報が多すぎるかもしれませんし、十分でないかもしれません。いずれにせよ、うまくいけば、コードを追加することで、先に進むための情報を提供できます...

4

1 に答える 1

1

-解決済み-

そして、それはとても簡単でした。私は最初の質問で正しかったので、それを理解するのにこれほど長い時間がかかったことに驚いています-それは単純な足し算と引き算でした:

すべての変換は、ポリゴンをレンダリングするメソッド内で行われるようになりました。多角形の各点について、州のビューの原点を追加し、郡の境界ボックスの原点を差し引いてから、Y 値 (コントロール バーの高さ) から 44 を引く必要がありました。

これは、問題を考えすぎてイライラし、さらに考えすぎて、3日後に答えがあなたの顔を見つめ、赤旗を振って、「私はここにいるよ!!!!」

于 2011-06-13T11:57:00.437 に答える