- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我已经为这个问题搜索了很多,但似乎没有一个能完全符合我的要求。很多教程向我展示了如何在代码中添加线条和多边形,但没有使用手绘图。
问题如下:
我正在构建一个房地产应用程序。如果用户在 MKMapView
上,它可以在他/她想买/租房子的特定区域周围绘制一个矩形/圆形/...。然后我需要在用户选择的区域内显示对应的结果。
目前,我在 MKMapView
之上有一个 UIView
,我在其中进行了一些自定义绘图,有没有一种方法可以将点转换为坐标,或者..?或者这完全不是这样做的方式?我也听说过 MKMapOverlayView
等。但我不确定如何使用它。
谁能给我指出正确的方向,或者他有一些示例代码或教程可以帮助我完成我需要的东西吗?
谢谢
最佳答案
我有一个基本上可以执行此操作的应用程序。我有一个 map View ,屏幕顶部有一个工具栏。当您按下该工具栏上的按钮时,您现在处于可以在 map 上滑动手指的模式。滑动的开始和结束将代表矩形的角。该应用程序将绘制一个半透明的蓝色矩形叠加层以显示您选择的区域。当您抬起手指时,矩形选择完成,应用开始在我的数据库中搜索位置。
我不处理圆圈,但我认为您可以做类似的事情,其中有两种选择模式(矩形或圆形)。在圆形选择模式下,滑动起点和终点可以代表圆心和边缘(半径)。或者,直径线的两端。我会把那部分留给你。
首先,我定义了一个处理选择的透明覆盖层 (OverlaySelectionView.h):
#import <QuartzCore/QuartzCore.h>
#import <MapKit/MapKit.h>
@protocol OverlaySelectionViewDelegate
// callback when user finishes selecting map region
- (void) areaSelected: (CGRect)screenArea;
@end
@interface OverlaySelectionView : UIView {
@private
UIView* dragArea;
CGRect dragAreaBounds;
id<OverlaySelectionViewDelegate> delegate;
}
@property (nonatomic, assign) id<OverlaySelectionViewDelegate> delegate;
@end
和 OverlaySelectionView.m:
#import "OverlaySelectionView.h"
@interface OverlaySelectionView()
@property (nonatomic, retain) UIView* dragArea;
@end
@implementation OverlaySelectionView
@synthesize dragArea;
@synthesize delegate;
- (void) initialize {
dragAreaBounds = CGRectMake(0, 0, 0, 0);
self.userInteractionEnabled = YES;
self.multipleTouchEnabled = NO;
self.backgroundColor = [UIColor clearColor];
self.opaque = NO;
self.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
}
- (id) initWithCoder: (NSCoder*) coder {
self = [super initWithCoder: coder];
if (self != nil) {
[self initialize];
}
return self;
}
- (id) initWithFrame: (CGRect) frame {
self = [super initWithFrame: frame];
if (self != nil) {
[self initialize];
}
return self;
}
- (void)drawRect:(CGRect)rect {
// do nothing
}
#pragma mark - Touch handling
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch* touch = [[event allTouches] anyObject];
dragAreaBounds.origin = [touch locationInView:self];
}
- (void)handleTouch:(UIEvent *)event {
UITouch* touch = [[event allTouches] anyObject];
CGPoint location = [touch locationInView:self];
dragAreaBounds.size.height = location.y - dragAreaBounds.origin.y;
dragAreaBounds.size.width = location.x - dragAreaBounds.origin.x;
if (self.dragArea == nil) {
UIView* area = [[UIView alloc] initWithFrame: dragAreaBounds];
area.backgroundColor = [UIColor blueColor];
area.opaque = NO;
area.alpha = 0.3f;
area.userInteractionEnabled = NO;
self.dragArea = area;
[self addSubview: self.dragArea];
[dragArea release];
} else {
self.dragArea.frame = dragAreaBounds;
}
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
[self handleTouch: event];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
[self handleTouch: event];
if (self.delegate != nil) {
[delegate areaSelected: dragAreaBounds];
}
[self initialize];
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
[self initialize];
[self.dragArea removeFromSuperview];
self.dragArea = nil;
}
#pragma mark -
- (void) dealloc {
[dragArea release];
[super dealloc];
}
@end
然后我有一个实现上面定义的协议(protocol)的类 (MapViewController.h):
#import "OverlaySelectionView.h"
typedef struct {
CLLocationDegrees minLatitude;
CLLocationDegrees maxLatitude;
CLLocationDegrees minLongitude;
CLLocationDegrees maxLongitude;
} LocationBounds;
@interface MapViewController : UIViewController<MKMapViewDelegate, OverlaySelectionViewDelegate> {
LocationBounds searchBounds;
UIBarButtonItem* areaButton;
在我的 MapViewController.m 中,areaSelected
方法是我使用 convertPoint:toCoordinateFromView:
将触摸坐标转换为地理坐标的地方:
#pragma mark - OverlaySelectionViewDelegate
- (void) areaSelected: (CGRect)screenArea
{
self.areaButton.style = UIBarButtonItemStyleBordered;
self.areaButton.title = @"Area";
CGPoint point = screenArea.origin;
// we must account for upper nav bar height!
point.y -= 44;
CLLocationCoordinate2D upperLeft = [mapView convertPoint: point toCoordinateFromView: mapView];
point.x += screenArea.size.width;
CLLocationCoordinate2D upperRight = [mapView convertPoint: point toCoordinateFromView: mapView];
point.x -= screenArea.size.width;
point.y += screenArea.size.height;
CLLocationCoordinate2D lowerLeft = [mapView convertPoint: point toCoordinateFromView: mapView];
point.x += screenArea.size.width;
CLLocationCoordinate2D lowerRight = [mapView convertPoint: point toCoordinateFromView: mapView];
searchBounds.minLatitude = MIN(lowerLeft.latitude, lowerRight.latitude);
searchBounds.minLongitude = MIN(upperLeft.longitude, lowerLeft.longitude);
searchBounds.maxLatitude = MAX(upperLeft.latitude, upperRight.latitude);
searchBounds.maxLongitude = MAX(upperRight.longitude, lowerRight.longitude);
// TODO: comment out to keep search rectangle on screen
[[self.view.subviews lastObject] removeFromSuperview];
[self performSelectorInBackground: @selector(lookupHistoryByArea) withObject: nil];
}
// this action is triggered when user selects the Area button to start selecting area
// TODO: connect this to areaButton yourself (I did it in Interface Builder)
- (IBAction) selectArea: (id) sender
{
PoliteAlertView* message = [[PoliteAlertView alloc] initWithTitle: @"Information"
message: @"Select an area to search by dragging your finger across the map"
delegate: self
keyName: @"swipe_msg_read"
cancelButtonTitle: @"Ok"
otherButtonTitles: nil];
[message show];
[message release];
OverlaySelectionView* overlay = [[OverlaySelectionView alloc] initWithFrame: self.view.frame];
overlay.delegate = self;
[self.view addSubview: overlay];
[overlay release];
self.areaButton.style = UIBarButtonItemStyleDone;
self.areaButton.title = @"Swipe";
}
您会注意到我的 MapViewController
有一个属性 areaButton
。这是我工具栏上的一个按钮,通常显示为 Area。用户按下后,他们处于区域选择模式,此时按钮标签变为滑动以提醒他们滑动(可能不是最好的 UI,但这就是我所拥有的)。
另请注意,当用户按下 Area 进入区域选择模式时,我会向他们显示一个警告,告诉他们需要滑动。因为这可能只是他们需要看一次的提醒,所以我使用了自己的 PoliteAlertView ,这是一个自定义的 UIAlertView
,用户可以抑制(不再显示警报)。
我的 lookupHistoryByArea
只是一种通过保存的 searchBounds
(在后台)在我的数据库中搜索位置的方法,然后在 map 上绘制新的叠加层找到的位置。对于您的应用,这显然会有所不同。
因为这是为了让用户选择近似区域,所以我认为地理精度不是很重要。它听起来也不应该在您的应用程序中。因此,我只画了 90 度角的矩形,不考虑地球曲率等。对于只有几英里的区域,这应该没问题。
我不得不对您的短语touch based drawing 做出一些假设。我决定,实现该应用程序的最简单方法,也是触摸屏用户最容易使用的方法,就是通过一次滑动来简单地定义区域。 绘制带触摸的矩形需要 4 次滑动而不是一次,引入非封闭矩形的复杂性,产生草率的形状,并且可能无法让用户获得他们想要的东西。所以,我试图保持 UI 简单。如果你真的想让用户在 map 上绘图,see this related answer which does that .
此应用是在 ARC 之前编写的,未针对 ARC 进行更改。
在我的应用程序中,我确实对在主 (UI) 线程、和 后台(搜索)线程中访问的一些变量使用了互斥锁。我为这个例子取出了那个代码。根据您的数据库搜索的工作方式以及您选择运行搜索的方式(GCD 等),您应该确保审核自己的线程安全。
关于iOS + MKMapView 用户触摸绘图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14374240/
我正在尝试编写一个函数来制作绘图并将其自动保存到文件中。 我努力用它来动态地做的技巧[plotname=varname & filename=varname &], 并使其与从循环中调用它兼容。 #
有人可以帮助我如何在绘图条形图中添加“下拉”菜单。 我在以下链接 ( https://plot.ly/python/v3/dropdowns/ ) 上找到了一些信息,但我正在努力调整代码,因此下拉选项
我不确切知道如何表达这一点,但我本质上希望根据其他数据之前的列值将数据分组为 Excel 图的系列。例如: size weight apple 3 35 orange 4
我正在为出版物创建图表并希望它们具有相同的字体大小。 当我用多图创建图形时,字体大小会减小,即使我没有更改tiff() 分辨率或pointsize 参数。我根据最终适合的地 block 数量增加了图形
我用 glm::perspective(80.0f, 4.0f/3.0f, 1.0f, 120.0f);并乘以 glm::mat4 view = glm::lookAt( glm::vec3(
我在 Shiny UI 中有一个情节。如果我更改任何输入参数并且通过 react 性图将会改变。但是让我们考虑以下情况:- Shiny UI 中的绘图可以说股票的日内价格变动。为此,您查询一些实时数据
我对 R 有点陌生。我在以下两个线程中跟踪并实现了结果: http://tolstoy.newcastle.edu.au/R/e17/help/12/03/7984.html http://lukem
我想在 WPF 控件中使用 GDI+ 绘图。 最佳答案 有多种方法可以做到这一点,最简单的方法是锁定您使用 GDI 操作的位图,获取像素缓冲区(从锁定中获取的 BitmapData 中的 Scan0
如何在以下取自其网站的绘图示例中隐藏颜色条? df % layout(title = '2014 Global GDPSource:CIA World Factbook',
我有两列数据,X 和 Y,每个条目在两个向量的小数点后都有 4 位数据。 当我使用 plot(x,y) 绘制简单图时,轴上显示的数据精确到小数点后两位。如何在两个轴上将其更改为小数点后 4 位精度?
我目前正在使用 Canvas 处理 JavaFX-Drawing-Application。在 GraphicsContext 的帮助下,我使用 beginPath() 和 lineTo() 方法绘制线
如果这个问题已经得到解答,但我无法找到我需要的东西,我提前道歉。我想从名为 data1.dat、data2.dat 的文件中绘制一些结果......我设法通过循环导入数据,但我无法使用循环绘制结果。仅
我的 pandas 数据框中有一个功能,可以(可能)具有多个级别。我可以使用以下方法获得独特的级别: reasons = df["Reason"].unique() 我可以通过执行以下操作在单个图表上
我在 Ubuntu 14 和 Windows 7(均为 64 位)中用 Python 绘制结果时遇到问题。作为一个简单的比较,我做了: from tvb.simulator.lab import *
以下代码相当简单 - 它用随机选择的像素填充设计表面 - 没什么特别的(暂时忽略第二种方法中的 XXXXXXX)。 private void PaintBackground() { Rando
我正在尝试制作一个绘制函数图形的 swing 应用程序(现在很简单,例如 x+2)但我在根据屏幕坐标制作我的点的数学坐标时遇到问题。我希望它在我的图表中简单地画一条从 P1(0,1) 到 P2(1,2
编辑 4:问题的新格式 背景:我有一个扩展 JFrame 的类 Window,在 JFrame 中我有一个 Canvas 。我向 Canvas 添加自定义对象。这个对象的唯一目的(为了争论)是在 Ca
我需要为即将到来的锦标赛标记阶梯,但我找不到任何方法来语义标记它。到目前为止我看到的唯一方法是 mark it up as a table ,我想不惜一切代价避免这种情况。 有什么想法吗? 最佳答案
我目前正在为一个小型 uC 项目编写 UI。在计算垂直线的位置时遇到一些问题。这个想法是将红线沿 x 轴移动到矩形的末端。 使用无限旋转编码器递增的值,范围为 0 到 800,增量为 1。矩形的左侧是
我正在尝试绘制光分布图。我想准确地执行此问题的第一步所要求的:Statistical analysis on Bell shaped (Gaussian) curve . 现在我有一组值。我希望数组元
我是一名优秀的程序员,十分优秀!