关于地图api:GCJ02高德-BD09百度-WGS84谷歌坐标系之间的转换

WGS-84、GCJ-02、BD-09 坐标系先理解一下WGS-84、GCJ-02、BD-09 坐标系别离是什么WGS84(World Geodetic System 1984):是 GPS 全球定位系统建设的坐标零碎,通过GPS定位拿到的原始经纬度。GCJ-02(国家测量局02号规范):GCJ-02 是由中国国家测绘局(G示意Guojia国家,C示意Cehui测绘,J示意Ju局)制订的地理信息系统的坐标零碎,是在WGS84经纬度的根底上执行加密算法而成。因为GPS失去的经纬度间接在 GCJ-02 坐标系下会定位到谬误的地点,有种到了火星的感觉,因而在坊间也将 GCJ-02 戏称为火星坐标系。国内的高德地图就是用的 GCJ-02 坐标系BD-09(Baidu, BD):是百度地图应用的天文坐标系,其在GCJ-02上多减少了一次变换,用来爱护用户隐衷。从百度产品中失去的坐标都是BD-09坐标系。WGS-84、GCJ-02、BD-09 坐标系之间的转换新建一个 js 文件,间接把上面的代码copy进去。在须要应用的中央导入就能够调用上面的各个转换方法了 —.— /** * 判断经纬度是否超出中国境内 */function isLocationOutOfChina(latitude, longitude) { if (longitude < 72.004 || longitude > 137.8347 || latitude < 0.8293 || latitude > 55.8271) return true; return false;}/** * 将WGS-84(国际标准)转为GCJ-02(火星坐标): */function transformFromWGSToGCJ(latitude, longitude) { var lat = ""; var lon = ""; var ee = 0.00669342162296594323; var a = 6378245.0; var pi = 3.14159265358979324; if (isLocationOutOfChina(latitude, longitude)) { lat = latitude; lon = longitude; } else { var adjustLat = transformLatWithXY(longitude - 105.0, latitude - 35.0); var adjustLon = transformLonWithXY(longitude - 105.0, latitude - 35.0); var radLat = latitude / 180.0 * pi; var magic = Math.sin(radLat); magic = 1 - ee * magic * magic; var sqrtMagic = Math.sqrt(magic); adjustLat = (adjustLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi); adjustLon = (adjustLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi); latitude = latitude + adjustLat; longitude = longitude + adjustLon; } return { latitude: latitude, longitude: longitude };}/** * 将GCJ-02(火星坐标)转为百度坐标(DB-09): */function transformFromGCJToBaidu(latitude, longitude) { var pi = 3.14159265358979324 * 3000.0 / 180.0; var z = Math.sqrt(longitude * longitude + latitude * latitude) + 0.00002 * Math.sin(latitude * pi); var theta = Math.atan2(latitude, longitude) + 0.000003 * Math.cos(longitude * pi); var a_latitude = (z * Math.sin(theta) + 0.006); var a_longitude = (z * Math.cos(theta) + 0.0065); return { latitude: a_latitude, longitude: a_longitude };}/** * 将百度坐标(DB-09)转为GCJ-02(火星坐标): */function transformFromBaiduToGCJ(latitude, longitude) { var xPi = 3.14159265358979323846264338327950288 * 3000.0 / 180.0; var x = longitude - 0.0065; var y = latitude - 0.006; var z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * xPi); var theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * xPi); var a_latitude = z * Math.sin(theta); var a_longitude = z * Math.cos(theta); return { latitude: a_latitude, longitude: a_longitude };}/** * 将GCJ-02(火星坐标)转为WGS-84(国际标准): */function transformFromGCJToWGS(latitude, longitude) { var threshold = 0.00001; // The boundary var minLat = latitude - 0.5; var maxLat = latitude + 0.5; var minLng = longitude - 0.5; var maxLng = longitude + 0.5; var delta = 1; var maxIteration = 30; while (true) { var leftBottom = transformFromWGSToGCJ(minLat, minLng); var rightBottom = transformFromWGSToGCJ(minLat, maxLng); var leftUp = transformFromWGSToGCJ(maxLat, minLng); var midPoint = transformFromWGSToGCJ((minLat + maxLat) / 2, (minLng + maxLng) / 2); delta = Math.abs(midPoint.latitude - latitude) + Math.abs(midPoint.longitude - longitude); if (maxIteration-- <= 0 || delta <= threshold) { return { latitude: (minLat + maxLat) / 2, longitude: (minLng + maxLng) / 2 }; } if (isContains({ latitude: latitude, longitude: longitude }, leftBottom, midPoint)) { maxLat = (minLat + maxLat) / 2; maxLng = (minLng + maxLng) / 2; } else if (isContains({ latitude: latitude, longitude: longitude }, rightBottom, midPoint)) { maxLat = (minLat + maxLat) / 2; minLng = (minLng + maxLng) / 2; } else if (isContains({ latitude: latitude, longitude: longitude }, leftUp, midPoint)) { minLat = (minLat + maxLat) / 2; maxLng = (minLng + maxLng) / 2; } else { minLat = (minLat + maxLat) / 2; minLng = (minLng + maxLng) / 2; } }}function isContains(point, p1, p2) { return (point.latitude >= Math.min(p1.latitude, p2.latitude) && point.latitude <= Math.max(p1.latitude, p2.latitude)) && (point.longitude >= Math.min(p1.longitude, p2.longitude) && point.longitude <= Math.max(p1.longitude, p2.longitude));}function transformLatWithXY(x, y) { var pi = 3.14159265358979324; var lat = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x)); lat += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0; lat += (20.0 * Math.sin(y * pi) + 40.0 * Math.sin(y / 3.0 * pi)) * 2.0 / 3.0; lat += (160.0 * Math.sin(y / 12.0 * pi) + 320 * Math.sin(y * pi / 30.0)) * 2.0 / 3.0; return lat;}function transformLonWithXY(x, y) { var pi = 3.14159265358979324; var lon = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x)); lon += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0; lon += (20.0 * Math.sin(x * pi) + 40.0 * Math.sin(x / 3.0 * pi)) * 2.0 / 3.0; lon += (150.0 * Math.sin(x / 12.0 * pi) + 300.0 * Math.sin(x / 30.0 * pi)) * 2.0 / 3.0; return lon;}module.exports = { isLocationOutOfChina: isLocationOutOfChina, transformFromWGSToGCJ: transformFromWGSToGCJ, transformFromGCJToBaidu: transformFromGCJToBaidu, transformFromBaiduToGCJ: transformFromBaiduToGCJ, transformFromGCJToWGS: transformFromGCJToWGS}总结为了不便浏览,我把这些坐标系别离用百度地图、高德地图、谷歌地图这些产品名字代替了,谷歌坐标系(WGS-84)、高德坐标系(GCJ-02)、百度坐标系(BD-09)。 ...

July 21, 2022 · 4 min · jiezi

地图中添加沿线文字标注

以下内容转载自工程师Nero8421 的文章《 地图中添加沿线文字标注》作者:Nero8421 链接:https://www.cnblogs.com/Allen...来源:博客园著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。最近需要实现导航功能,其中路线规划和导航场景如下图所示: 上面的截图中,路线上面都绘制出了路名,方便用户查看自己选择的路线都经过了哪些道路。这里用到的地图的能力即为沿线文字标注腾讯地图 Android SDK v4.2.7 已经开放了实现此功能的能力。 主要涉及接口如下: 接口名称功能概述PolylineOptions.text(Text text)置沿 polyline 展示的文字PolylineOptions.Text.Builder(SegmentText segmentTextPolylineOptions.Text 构造器PolylineOptions.Text.Builder.addSegmentText(SegmentText segmentText)添加线上展示文字的点串范围PolylineOptions.Text.Builder.color(int color)设置文字颜色PolylineOptions.Text.Builder.strokeColor(int color)设置文字描边颜色PolylineOptions.Text.Builder.size(int size)设置文字尺寸PolylineOptions.Text.Builder.priority(TextPriority priority)设置文字优先级从这个功能涉及到的接口可以看出沿线文字标注是作为 Polyline 的一个属性供用户在添加线的时候展示所需文字。 为一条线添加文字标注1、选择合适的点串作为文字标注的路径。如下,我们选择了 苏州街-北四环西路辅路-彩和坊路 的一个点串作为 Polyline 绘制的路径。 //这一个点串表示了经 苏州街-北四环-彩和坊路 的一条路线List<LatLng> points = new ArrayList<>();//苏州街points.add(new LatLng(39.982382, 116.305883));//北四环西路辅路points.add(new LatLng(39.984914, 116.305690));//彩和坊路points.add(new LatLng(39.985045, 116.308136));points.add(new LatLng(39.983570, 116.308088));points.add(new LatLng(39.980063, 116.308297));2、绘制 Polyline 及其文字标注 public Polyline createLineWithText() { if (mTencentmap == null) { return null; } Polyline polyline = mTencentmap.addPolyline( new PolylineOptions() .addAll(points) .color(0xff54ce4d) .text(createText())); return polyline;}public PolylineOptions.Text createText() { List<PolylineOptions.SegmentText> segmentTexts = new ArrayList<>(); //苏州街 的绘制范围是从第0个点开始,第1个点结束 segmentTexts.add(new PolylineOptions.SegmentText(0, 1, "苏州街")); //北四环西路辅路 的绘制范围是从第1个点开始,第2个点结束 segmentTexts.add(new PolylineOptions.SegmentText(1, 2, "北四环西路辅路")); //彩和坊路 的绘制范围是从第2个点开始,第4个点结束 segmentTexts.add(new PolylineOptions.SegmentText(2, 4, "彩和坊路")); return new PolylineOptions.Text.Builder(segmentTexts).build();}最终的效果: ...

October 14, 2019 · 1 min · jiezi

地图-SDK-系列教程在地图上展示指定区域

以下内容转载自iOS 工程师Genosage的文章《地图 SDK 系列教程-在地图上展示指定区域》 作者:Genosage链接:https://juejin.im/post/5d721a... 来源:掘金著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。地图SDK系列教程-在地图上展示指定区域在使用腾讯 iOS 地图 SDK 的过程中,经常会遇到需要地图展示指定区域的场景,相信大家也会遇到类似的情况,地图 SDK 提供了许多与之相关的接口,本篇文章将对这些接口进行整合,并提供示例代码来实现多个场景下展示指定区域的需求。 需要注意,本篇文章适用于地图未发生旋转与俯仰角的场景。 下载腾讯 iOS 地图 SDK 请前往:iOS 地图 SDK 指定区域包含单个坐标点在地图上显示某个固定的坐标点是地图 SDK 最为基础的功能之一。 举例来说,我们根据 SDK 的检索功能得到了天坛公园的坐标 (39.881190,116.410490),接下来,我们可以通过设置地图的中心点 centerCoordinate 来让地图显示这个坐标,同时我们还可以设置 zoomLevel 来指定缩放级别: // 设置中心点self.mapView.centerCoordinate = CLLocationCoordinate2DMake(39.881190,116.410490); // 设置缩放级别self.mapView.zoomLevel = 15;显示效果如下: 如果想展示墨卡托坐标点 QMapPoint 则需要先通过方法 QCoordinateForMapPoint(QMapPoint mapPoint) 将墨卡托坐标转换为经纬度再进行设置。 指定区域包含多个坐标点现在,假如我们想把天坛公园的搜索结果都显示在地图上,应该如何实现呢? 首先,我们通过检索功能搜索天坛公园,取搜索结果的前九个坐标点,接下来,应该使我们的地图视野包含这九个坐标点,地图 SDK 提供了方法 QBoundingCoordinateRegionWithCoordinates(CLLocationCoordinate2D *coordinates, NSUInteger count) 来计算多个经纬度坐标点的最小外接矩形 QCoordinateRegion 在得到了外接矩形之后,我们可以直接设置地图的 region 来使其显示我们想要的区域,完整代码如下: CLLocationCoordinate2D coordinates[9];// 天坛公园检索结果坐标coordinates[0] = CLLocationCoordinate2DMake(39.881190,116.410490);coordinates[1] = CLLocationCoordinate2DMake(39.883247,116.400063);coordinates[2] = CLLocationCoordinate2DMake(39.883710,116.412900);coordinates[3] = CLLocationCoordinate2DMake(39.883654,116.412863);coordinates[4] = CLLocationCoordinate2DMake(39.883320,116.400040);coordinates[5] = CLLocationCoordinate2DMake(39.876980,116.413190);coordinates[6] = CLLocationCoordinate2DMake(39.878160,116.413140);coordinates[7] = CLLocationCoordinate2DMake(39.878980,116.407080);coordinates[8] = CLLocationCoordinate2DMake(39.878560,116.413160); // 计算区域外接矩形QCoordinateRegion region = QBoundingCoordinateRegionWithCoordinates(coordinates, 9); // 设置区域self.mapView.region = region;显示效果如下: ...

October 14, 2019 · 2 min · jiezi

天地图之定位信息详解

原文首发于微信公众号:jzman-blog,欢迎关注交流!最近的项目涉及到百度地图的使用,项目组通知使用天地图替代百度地图,一个原因是天地图是国家测绘地理信息局建设的,企业可以使用其公众版本进行开发以提供相关的地图信息服务,较其他地图具有权威性,当然天地图提供的服务是否较其他地图更具有权威性和实时性,这个作为普通开发者是不能确定的,另一个原因是减少运用成本,我觉得是否真能达到这样的目标真不一定,毕竟商业地图输出能力还是较免费版本更强。还是先来开始天地图 Android SDK 的学习之路吧,先从一下几个方面来学习: 引入天地图 SDK地图显示我的位置定位图标的修改获取位置信息显示效果引入天地图 SDK首先下载天地图地图 SDK,然后添加相应的 Jar 包和 so 文件到 libs 文件夹中,在 module 的 build.gradle 文件中指定 so 文件的目录为 libs 目录,具体如下: sourceSets { main { //指定so文件的查找目录是libs目录 jniLibs.srcDir 'libs' }}按照官网指定的权限配置,使用过程中发现少了权限,下面是完整权限列表,具体如下: <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /><uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /><uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.CALL_PHONE" /><uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /><uses-permission android:name="android.permission.READ_PHONE_STATE" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />如果项目 targetSdkVersion 是 23 以上记得动态申请相关危险权限,此时,天地图地图 SDK 就引入到项目中了。 地图显示首先在布局中引入 MapView,布局代码如下: <com.tianditu.android.maps.MapView android:id="@+id/mapView" android:layout_width="match_parent" android:layout_height="match_parent"/>此时,地图就可以正常显示了,不需要额外的配置,当然可以初始化地图相关的一些参数,常用配置如下: private void initMapView() { //启用内置的缩放组件 mapView.setBuiltInZoomControls(true); //得到MapView的控制权,可以用它控制和驱动平移和缩放 mMapController = mapView.getController(); //用给定的经纬度构造一个GeoPoint,单位是微度 (度 * 1E6) GeoPoint point = new GeoPoint((int) (39.915 * 1E6), (int) (116.404 * 1E6)); //设置地图中心点 mMapController.setCenter(point); //设置地图缩放级别 mMapController.setZoom(12);}天地图 Android SDK 的引入及地图显示相对百度地图、高德地图还是比较方便的。 ...

May 16, 2019 · 2 min · jiezi