项目需求

指定某区域(非省市区县乡镇标准行政区划),做功能边界分区,实现Echarts地理坐标数据可视化展示。

提供信息

项目分析

  • 要在Echarts上实现地理坐标可视化,必须使用geoJSON格式文件;
  • 项目只能提供手绘图纸,需要将手绘图纸转换为可以识别的经纬度坐标信息;
  • 如何将图纸绑定在百度地图上,使图纸和百度地图区域相重合,按照提供的区域边界,拾取对应的经纬度坐标;
  • 将拾取的经纬度坐标做换为geoJSON;
  • 引入Echarts,进行开发;

操作步骤

为简化流程和项目信息外漏,以随意某地作为案例实施步骤演示。

固定地图

在百度地图上找到对应的区域,并设置对应的地图显示级别,map.centerAndZoom(new BMap.Point(112.761393, 28.101516), 18)方便后面图片和区域相重合;截图固定地图级别的图片:map1.jpg

图片处理

在PSD中打开map1.jpg文件,将功能区划在PSD中进行处理,扣除多余的部分,只要行政划分的区域,且图片的大小依据步骤1中截图的大小,一一对应。

3.隐藏地图,只留行政区划部分区域,保存新的文件为:newmap.png

代码开发

使用的技能:

  1. 百度地图API的引入;
  2. 百度地图绘制多边形并获取所有点的坐标;
  3. HTML&CSS相对定位和绝对定位,实现图片和地图的重合;
  4. 将拾取的坐标转化为标准的geoJOSN;

引入百度地图api

    <script type="text/javascript"
src="http://api.map.baidu.com/api?v=3.0&ak=你的AK"></script>

创建容器

<div id="main">
<div id="img"><img src="data:images/lll.png" alt=""></div>
<div id="container"></div>
</div>
<div id="text"><input id="startBtn" type="button" onclick="startTool();" value="开启取点"/>
<input type="button" onclick="map.clearOverlays();document.getElementById('info').innerHTML = '';points=[];"
value="清除"/>
</div> <div id="info">坐标:</div>

CSS样式表

  body, html {

            width: 100%;
height: 100%;
margin: 0;
font-family: "微软雅黑";
} #main { position: relative;
} #img { position: absolute;
opacity: 0.5;
left: 500px;
top: 200px;
z-index: -999;
} #container { width: 100%;
height: 80vh;
border: 1px solid gray;
position: absolute;
opacity: 0.7;
z-index: 9999;
} #text { position: absolute;
z-index: 9999;
left: 50px;
bottom: 120px;
} #info { position: absolute;
z-index: 999999;
left: 50px;
bottom: 80px;
}

实现的布局如图:

  1. 图片置于最底层,方便按照边界拾取经纬度;
  2. 地图设置一定的透明度,方便开发图片;
  3. 移动地图和图片相重合,绘制多边形并获取所有点的坐标;

绘制多边形并获取所有点的坐标

var map = new BMap.Map("container", {

   enableMapClick: false});
map.centerAndZoom(new BMap.Point(112.761393, 28.101516), 18);
map.enableScrollWheelZoom(); /*设置版权控件位置 -Begin*/
var cr = new BMap.CopyrightControl({ anchor: BMAP_ANCHOR_TOP_RIGHT});
map.addControl(cr); //添加版权控件
var bs = map.getBounds(); //返回地图可视区域
cr.addCopyright({ id: 1,
content: "<div style='font-size:12px;margin: 10px;padding:5px;background: rgba(255,255,255,.8);'>Copyright �0�8 漏刻有时百度地图API开发</div>",
bounds: bs
});
/*设置版权控件位置 -End*/ var key = 1; //开关
var newpoint; //一个经纬度
var points = []; //数组,放经纬度信息
var polyline = new BMap.Polyline(); //折线覆盖物 function startTool() { //开关函数
if (key == 1) { document.getElementById("startBtn").style.background = "green";
document.getElementById("startBtn").style.color = "white";
document.getElementById("startBtn").value = "开启状态";
key = 0;
}
else { document.getElementById("startBtn").style.background = "red";
document.getElementById("startBtn").value = "关闭状态";
key = 1;
}
} //单击地图,形成折线覆盖物
map.addEventListener("click", function (e) { newpoint = new BMap.Point(e.point.lng, e.point.lat);
if (key == 0) { // if(points[points.length].lng==points[points.length-1].lng){alert(111);}
points.push(newpoint); //将新增的点放到数组中
polyline.setPath(points); //设置折线的点数组
map.addOverlay(polyline); //将折线添加到地图上
/*02.数据集格式*/
document.getElementById("info").innerHTML += "[" + e.point.lng + "," + e.point.lat + "],"; }
}); //双击地图,形成多边形覆盖物
map.addEventListener("dblclick", function (e) { if (key == 0) { map.disableDoubleClickZoom(); //关闭双击放大
var polygon = new BMap.Polygon(points);
map.addOverlay(polygon); //将折线添加到地图上
}
});

[112.7584914732037,28.10156777873837],[112.759075371785,28.1008667598055],[112.76014435534152,28.10005420934206],[112.76070130475752,28.10014183763234],[112.76055757587598,28.10128099882524],[112.76028808422306,28.101519982139973],[112.7585094393139,28.101599643125347]

生成geoJSON

{

  "type": "FeatureCollection",
"features": [
{ "type": "Feature",
"properties": { },
"geometry": { "type": "LineString",
"coordinates": [
[
112.7584914732037,
28.10156777873837
],
[
112.759075371785,
28.1008667598055
],
[
112.76014435534152,
28.10005420934206
],
[
112.76070130475752,
28.10014183763234
],
[
112.76055757587598,
28.10128099882524
],
[
112.76028808422306,
28.101519982139973
],
[
112.7585094393139,
28.101599643125347
]
]
}
}
]
}

后续总结

  1. 第一种尝试,是使用百度标注,将图片作为一个maker使用,好在maker可以自由移动,方便对齐区域;而实际上,将图片引入百度地图API后,是无法缩放的,实现不了图片和地图的重合;
  2. 第二种尝试,使用GroundOverlay,地面图层的叠加,难点在于无法确定可视范围的西南角SW和东北角NE,就无法精准位置;同时该功能无法调整图片大小,无法移动和缩放图片,也实现不了图片和地图的重合;
  3. 返璞归真,利用CSS层叠的概念,实现图片和地图自由移动的特性,实现图片和地图的重合。
  4. 完成项目,希望有时间将该功能整理成一个插件,以便解决乡镇边界,村级边界、经济开发区边界等等自定义项目的开发。

LOCKDATAV DONE!

根据指定手绘图纸照片行政区划自定义绘制对应区域边界生成geoJOSN的解决方案的更多相关文章

  1. Flutter 自定义绘制 View

    在 Flutter 中自定义 View 有两种方式: 组合已有控件 自定义绘制 如何自定义绘制 有两个类做这件事情: CustomPaint :会在绘制阶段提供一个 Canvas 画布 CustomP ...

  2. Flutter自定义绘制(1)- 绘制基础

    CustomPainter Flutter 中实现绘制的主要是CustomPainter类. 我们一般继承这个类,来使用它: class MyPainter extends CustomPainter ...

  3. [js开源组件开发]-手机端照片预览组件

    手机端照片预览组件 可怜的我用着华为3C手机,用别人现成的组件都好卡,为了适应我这种屌丝,于是自己简化写了一版的照片预览效果,暂时无缩放功能,以后可能有空再加吧,你也可以自己加下,这是个github上 ...

  4. Unity 扩展属性自定义绘制

    这么晚了准备睡觉的时候,去学习了一会. 发现一个标题好奇的点进去. 居然是自定义绘制属性.  在前几天这个问题把我难住了,没想到几分钟就能解决的问题. 我花了半天时间使用反射去解决...  如果我们想 ...

  5. 利用JFreeChart绘制股票K线图完整解决方案

    http://blog.sina.com.cn/s/blog_4ad042e50100q7d9.html 利用JFreeChart绘制股票K线图完整解决方案 (2011-04-30 13:27:17) ...

  6. ASP.NET Core 中的SEO优化(3):自定义路由匹配和生成

    前言 前两篇文章主要总结了CMS系统两个技术点在ASP.NET Core中的应用: <ASP.NET Core 中的SEO优化(1):中间件实现服务端静态化缓存> <ASP.NET ...

  7. JS组件系列——BootstrapTable+KnockoutJS实现增删改查解决方案(四):自定义T4模板快速生成页面

    前言:上篇介绍了下ko增删改查的封装,确实节省了大量的js代码.博主是一个喜欢偷懒的人,总觉得这些基础的增删改查效果能不能通过一个什么工具直接生成页面效果,啥代码都不用写了,那该多爽.于是研究了下T4 ...

  8. 错误 4 自定义工具错误: 无法生成服务引用“DepartMentService”的代码。请检查其他错

    原文:错误 4 自定义工具错误: 无法生成服务引用"DepartMentService"的代码.请检查其他错 问题:     错误 4 自定义工具错误: 无法生成服务引用" ...

  9. 2019-4-26-VisualStudio-开发文件自定义工具单文件生成工具

    title author date CreateTime categories VisualStudio 开发文件自定义工具单文件生成工具 lindexi 2019-04-26 10:49:32 +0 ...

随机推荐

  1. Challenging Common Assumptions in the Unsupervised Learning of Disentangled Representations

    目录 概 主要内容 Locatello F., Bauer S., Lucic M., R"{a}tsch G., Gelly S. Sch"{o}lkopf and Bachem ...

  2. Mybatis源码系列 执行流程(一)

    1.Mybatis的使用 public static void main(String[] args) throws IOException { //1.获取配置文件流 InputStream is ...

  3. <数据结构>XDOJ332.二叉排序树的判定

    问题与解答 问题描述 给定一个二叉树,判断其是否是一个有效的二叉排序树. 假设一个二叉排序树具有如下特征: 结点的左子树只包含小于当前结点的树. 结点的右子树只包含大于当前结点的树. 所有左子树和右子 ...

  4. Vue.js高效前端开发知识 • 【目录】

    持续更新中- 章节 内容 实践练习 Vue.js高效前端开发 • (实践练习) 第1章 Vue.js高效前端开发 • [ 一.初识Vue.js ] 第2章 Vue.js高效前端开发 • [ 二.Vue ...

  5. JavaScript交互式网页设计 • 【第1章 JavaScript 基本语法】

    全部章节   >>>> 本章目录 1.1 JavaScript 概述 1.1.1 JavaScript 简介 1.1.2 JavaScript 的概念和执行原理 1.1.3 J ...

  6. Swoole 进程管理模块 Process 之单进程的使用

    PHP 自带的 pcntl,存在很多不足,如: 没有提供进程间通信的功能: 不支持重定向标准输入和输出: 只提供了 fork 这样原始的接口,容易使用错误: Swoole\Process 提供了如下特 ...

  7. 桥接模式(python)

    from abc import ABCMeta, abstractmethod class Shape(metaclass=ABCMeta): def __init__(self, color): s ...

  8. ARP解析MAC地址的全过程(ARP的工作机制)

    以太网环境下,同一个网段的主机之间需要互相知道对方的MAC地址,才能访问. TCP/IP协议栈从上层到下层的封装过程中,第三层封装需要知道目的IP,第二层封装需要知道目的MAC. 目的IP一般由用户手 ...

  9. vue部署服务器以及解决部署到apache路由出现404

    最近在开发cms的时候使用Vue.js框架,利用vue-route.vue-cli结合webpack编写了一个单页路由项目,自己在服务器端配置apache.部署完成后,访问没问题,从页面中点击跳转就会 ...

  10. iframe页面二次登录问题

    原文链接:iframe页面二次登录问题 生产问题 问题背景 由于历史原因,公司内部系统有一些页面是基于iframe嵌入的其他系统的页面,之前一直运行正常,最近不知什么原因接连出现访问所有iframe页 ...