热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

在自定义地图控件中缩放和平移-Zoomingandpanninginacustommapcontrol

Imwonderingifanyonecanhelpmewiththisoratleastprovidepointersintherightdirection.I

I'm wondering if anyone can help me with this or at least provide pointers in the right direction. I can post code if required however, due to the nature of the question, there is a lot of it and hence why I haven't so far.

我想知道是否有人可以帮助我,或至少提供正确方向的指示。如果需要,我可以发布代码,但由于问题的性质,有很多,因此我没有到目前为止。

I have a custom control which represents a "map". On this "map" I can draw specific glyphs at specific latitude and longitude's. I use GPS behind the scenes to obtain a geographic fix location which I then feed into the map as its origin position.

我有一个代表“地图”的自定义控件。在这张“地图”上,我可以在特定的纬度和经度上绘制特定的字形。我在后台使用GPS获取地理定位位置,然后我将其作为原点位置输入地图。

All objects drawn to the map have their lat/long positions converted to easting and northings (using an algorithm similar to the Google Maps/Bing projection) before being converted to screen pixels.

在转换为屏幕像素之前,绘制到地图的所有对象都将其纬度/长度位置转换为东向和北向(使用类似于Google Maps / Bing投影的算法)。

I take the centre of my "map" control client region as the reference screen position. When the "map" is panned, I store the delta mouse movement as an offset which when added to the reference position, gives me the location to start drawing my origin grid (this is also where the GPS position links in).

我将“地图”控制客户区域的中心作为参考屏幕位置。当平移“地图”时,我将增量鼠标移动存储为偏移量,当添加到参考位置时,为我提供开始绘制原点网格的位置(这也是GPS位置链接的位置)。

I hope this is making sense so far...

我希望到目前为止这是有意义的......

Now, all works well so far - I can draw objects at specific latitude and longitudes and they all appear in their correct locations relative to the centre of the origin grid.

现在,到目前为止一切运行良好 - 我可以在特定纬度和经度绘制物体,它们都出现在相对于原始网格中心的正确位置。

The issue which I can't seem to get my head around is how to zoom the map and focus on a specific area - like when using Google Maps/Google Earth, the position underneath the cursor at the point of zooming stays the same. Crudely, I use a zoom system which just increases or decreases the number of metres represented by 100 screen pixels (I'd like a more logarithmic style zoom but that will come later).

我似乎无法理解的问题是如何缩放地图并专注于特定区域 - 就像使用谷歌地图/谷歌地球时,光标下方缩放点的位置保持不变。粗略地说,我使用的是一个变焦系统,它只增加或减少100个屏幕像素所代表的米数(我想要一个更对数的样式变焦,但稍后会出现)。

What happens when I zoom in is that zooming always keeps my grid origin in the same position (this is because I use an offset for panning the map - and the offset isn't affected by zoom) however I have no idea how to think through the more correct zoom system.

当我放大时会发生的变化是缩放始终使我的网格原点保持在相同位置(这是因为我使用偏移来平移地图 - 并且偏移不受缩放影响)但是我不知道如何思考更正确的变焦系统。

I appreciate that this is a lot of text with no code - I can post code but like I said, there is a heck of a lot of it! I'm also sure that I've not explained my scenario very well but I'd appreciate any help at all.

我很欣赏这是很多没有代码的文本 - 我可以发布代码,但就像我说的那样,有很多内容!我也很确定我没有很好地解释我的情景,但我会感激任何帮助。

1 个解决方案

#1


All calculations are preferably done in GPS units, and conversions to device units should be the very last step. With this in mind, the following design should resolve your problem, with the assumption that you can store latitude and longitude in a float type:

所有计算最好以GPS单位进行,转换到设备单元应该是最后一步。考虑到这一点,以下设计应解决您的问题,假设您可以在float类型中存储纬度和经度:

enter image description here

type
  TMapCOntrol= class(TCustomControl)
  protected
    procedure Paint; override;
  public
    Glyph: TBitmap;
    //These are known, in GPS-coördinate units:
    MapRect: TRectF;
    ZoomFactor: Single;
    ZoomOrigin: TPointF;
    GlyphOrigin: TPointF;
  end;

procedure TMapControl.Paint;
var
  ZoomWidth: Single;
  ZoomHeight: Single;
  ZoomRect: TRectF;
  Scale: Single;
  GlyphPoint: TPoint;
begin
  // Calculation in GPS units:
  ZoomWidth := MapRect.Width * ZoomFactor;
  ZoomHeight := ZoomWidth * ClientHeight / ClientWidth;
  ZoomRect.Left := ZoomOrigin.X - ZoomWidth / 2;
  ZoomRect.Top := ZoomOrigin.Y - ZoomHeight / 2;
  // Not required for calculation, but for future convenience:
  ZoomRect.Width := ZoomWidth;
  ZoomRect.Height := ZoomHeight;
  // Calculation in device units:
  Scale := ZoomWidth / ClientWidth;  
  GlyphPoint.X := Round((GlyphOrigin.X - ZoomRect.Left) / Scale);
  GlyphPoint.Y := Round((GlyphOrigin.Y - ZoomRect.Top) / Scale);
  Canvas.Draw(GlyphPoint.X - Glyph.Width div 2,
    GlyphPoint.Y - Glyph.Height div 2, Glyph);
end;

The zoom factor is the percentage of the part of the total map being viewed. The scale factor converts the size of that portion to the size of your control.

缩放系数是正在查看的总地图部分的百分比。比例因子将该部分的大小转换为控件的大小。

Now the above code has some assumptions, most notably that the zoom origin and the zoom factor are known. Also, the origin of the map is considered to be (0, 0), which is not strictly required, but it keeps calculations easy and is practical too. If these are not the case, that I suggest you mimic the above or redesign what should be considered input and what be output. Or you need to explain better, wíth code, which conversions and calculations you are already doing. (You do not need to post all code for that, just strip to the absolute essential.)

现在上面的代码有一些假设,最值得注意的是变焦原点和缩放因子是已知的。此外,地图的原点被认为是(0,0),这不是严格要求的,但它使计算变得容易并且也是实用的。如果不是这种情况,我建议你模仿上述内容或重新设计应该考虑的输入和输出内容。或者你需要更好地解释代码,你正在做的转换和计算。 (你不需要为此发布所有代码,只需剥离绝对必要的。)


推荐阅读
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • 解决Cydia数据库错误:could not open file /var/lib/dpkg/status 的方法
    本文介绍了解决iOS系统中Cydia数据库错误的方法。通过使用苹果电脑上的Impactor工具和NewTerm软件,以及ifunbox工具和终端命令,可以解决该问题。具体步骤包括下载所需工具、连接手机到电脑、安装NewTerm、下载ifunbox并注册Dropbox账号、下载并解压lib.zip文件、将lib文件夹拖入Books文件夹中,并将lib文件夹拷贝到/var/目录下。以上方法适用于已经越狱且出现Cydia数据库错误的iPhone手机。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • 在Docker中,将主机目录挂载到容器中作为volume使用时,常常会遇到文件权限问题。这是因为容器内外的UID不同所导致的。本文介绍了解决这个问题的方法,包括使用gosu和suexec工具以及在Dockerfile中配置volume的权限。通过这些方法,可以避免在使用Docker时出现无写权限的情况。 ... [详细]
  • Linux服务器密码过期策略、登录次数限制、私钥登录等配置方法
    本文介绍了在Linux服务器上进行密码过期策略、登录次数限制、私钥登录等配置的方法。通过修改配置文件中的参数,可以设置密码的有效期、最小间隔时间、最小长度,并在密码过期前进行提示。同时还介绍了如何进行公钥登录和修改默认账户用户名的操作。详细步骤和注意事项可参考本文内容。 ... [详细]
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 不同优化算法的比较分析及实验验证
    本文介绍了神经网络优化中常用的优化方法,包括学习率调整和梯度估计修正,并通过实验验证了不同优化算法的效果。实验结果表明,Adam算法在综合考虑学习率调整和梯度估计修正方面表现较好。该研究对于优化神经网络的训练过程具有指导意义。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • 本文介绍了Linux系统中正则表达式的基础知识,包括正则表达式的简介、字符分类、普通字符和元字符的区别,以及在学习过程中需要注意的事项。同时提醒读者要注意正则表达式与通配符的区别,并给出了使用正则表达式时的一些建议。本文适合初学者了解Linux系统中的正则表达式,并提供了学习的参考资料。 ... [详细]
  • 利用Visual Basic开发SAP接口程序初探的方法与原理
    本文介绍了利用Visual Basic开发SAP接口程序的方法与原理,以及SAP R/3系统的特点和二次开发平台ABAP的使用。通过程序接口自动读取SAP R/3的数据表或视图,在外部进行处理和利用水晶报表等工具生成符合中国人习惯的报表样式。具体介绍了RFC调用的原理和模型,并强调本文主要不讨论SAP R/3函数的开发,而是针对使用SAP的公司的非ABAP开发人员提供了初步的接口程序开发指导。 ... [详细]
author-avatar
丹丹2502912601
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有