これは数学の質問であると確信していますが、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];
}
}
この本は本当に情報が多すぎるかもしれませんし、十分でないかもしれません。いずれにせよ、うまくいけば、コードを追加することで、先に進むための情報を提供できます...