先说kml是什么?
KML 是一种文件格式,用于在地球浏览器(例如 Google 地球、Google 地图和 Google 地图移动版)中显示地理数据。
KML文件是谷歌公司创建的一种地标性文件。用于记录某一地点、或连续地点的时间、经度、纬度、海拔等地理信息数据,供GE等有关软件使用。
KML文件是种多功能的地理数据格式,在Google发展下,它可以将(link)网页、图片、模型..等各种媒体档案在Google Earth作完整的呈现。
有人问kml用什么打开,所有编辑器都可以,但是要显示效果就需要特定工具了如谷歌地球
那么我们利用kml能干什么?
个人认为kml本身就是一种介质没有任何,就是用来携带数据的容器,也就是一种确定的数据结构用来传递数据,和json数据没有本质区别。那么我们能用他做什么呢?其实就是地图的数据格式,只要我们把数据解析出来,想干什么就干什么嘛,比如在地图上绘制各种等值面,行政区划,覆盖物等等,虽然他可能来自不同的平台生成,但是在别的地方也是可以用的,比如google生成的kml我们也可以用在百度高德中绘制自己想要的东西。下面记录下本次项目中遇到的坑
项目中系统gis平台是使用arcgis做的,除了大的系统平台还需要一个移动端,移动端我们一直用的是百度和高德,以前做的等值面数据是以图片的方式直接覆盖到地图上,要么就是自己根据面数据绘制,数据结构都比较清晰,自己输出个json就可以了,但是本次则不同,第一次用了arcgis图层服务数据,第二次用了arcgis生成的kml文件。
这两次相对于以前来说主要就是文件解析这块了,arcgis的图层服务是可以直接调用json输出的,这样就可以直接解析,而kml则需要利用dom的解析方式或者正则表达式也可以使用工具直接转换成json格式再解析,这些都是比较简单的,问题的难点在于kml是动态生成的,这时候他的有些节点是动态的,有时候这个节点是个数组,有时候是个对象,有时候又会成空值,所以这块比较麻烦,需要多做几次判断。下面我们主要讲一下kml的实现中遇到的坑
我们先看一下实现效果
kml转json并解析
/** * 解析等值面数据 * @param filepath */ private void readFile(String filepath) { try { org.json.JSONObject jsob = XML.toJSONObject(filepath).getJSONObject("kml").getJSONObject("Document"); org.json.JSONArray jsonlatlon = jsob.getJSONObject("Folder").getJSONArray("Placemark"); org.json.JSONArray stylemap = jsob.getJSONArray("StyleMap"); org.json.JSONArray style = jsob.getJSONArray("Style"); setMapLine(stylemap, style, jsonlatlon); } catch (Exception e) { e.printStackTrace(); } }
剩下的应该很简单了,就是取值然后绘制了,kml的结构大概如下:
<?xml version="1.0" encoding="UTF-8"?><kml xmlns="http://www.opengis.net/kml/2.2"> <Document> <Name>E:\123\123.kml </Name> <StyleMap id="pg0"> <Pair> <key>normal</key> <styleUrl>#pgn0</styleUrl> </Pair> <Pair> <key>highlight</key> <styleUrl>#pgn</styleUrl> </Pair> </StyleMap> <Style id="pgn0"> <LineStyle> <color>FF000000</color> <width>0</width> </LineStyle> <PolyStyle> <color>FFFFFFFF</color> <fill>1</fill> </PolyStyle> </Style> <Folder> <name>E:\123\123.kml </name> <description>Generated using MeteoInfo</description> <styleUrl>#pg3</styleUrl> <Polygon> <outerBoundaryIs> <LinearRing> <coordinates>111.595,37.21504069164365 111.58064425863547,37.225 111.58,37.22568584335938 </coordinates> </LinearRing> </outerBoundaryIs> <innerBoundaryIs> <LinearRing> <coordinates>111.595,37.23492262145533 111.61,37.234608191833274 </coordinates> </LinearRing> </innerBoundaryIs> </Polygon> </Placemark> </Folder> </Document> </kml> 需要注意的地方是就是<styleUrl>#pg0</styleUrl>对应 <StyleMap id="pg0"> 对应 <Style id="pgn0">
这个对应起来就可以取到绘制的数据和面的描述数据了,
绘制代码如下:
points为面的点数据,linmapwidth边界线宽度,linmapcolor边界线颜色,polymapcolor填充颜色,polymapfill 该面积代表的区块等级,可以自定义数据 下面是利用百度地图绘制 private void addmapline(List<LatLng> points, int linmapwidth, String linmapcolor, String polymapcolor, int polymapfill ){ Object[] c_o = kmlColor(polymapcolor); int i = Color.parseColor("#80"+c_o[0]); // Color color = Color.valueOf(i); // int fill = Color.argb((Float) c_o[1], color.red(), color.green(), color.blue()); PolygonOptions mPolygonOptions = new PolygonOptions() .points(points) .fillColor(i) //.substring(2,polymapcolor.length())) ) // 填充颜色 77 // .stroke(new Stroke(linmapwidth, Color.parseColor("#"+linmapcolor ))) // 边框宽度和颜色 .zIndex(polymapfill); mBaiduMap.addOverlay(mPolygonOptions); }
整个绘制完毕后发现图是没问题ok了 ,但是刚绘制完发现区块颜色和pc端系统完全对不上,图例也对不上,灰常郁闷,最后把kml拿过来把颜色值取出来发现pc端系统完全没按这个颜色绘制,但是出来的图和图例是一模一样的,这时候就想是不是pc端同事改了绘制颜色,结果都说没有,那就怀疑上arcgis了,可能是在绘制的时候改过颜色了,于是把pc端系统把所有用到的js扒下来挨个读了一遍,果然有一块被处理了
最终找到颜色处理如下代码,我勒个擦,真的是很坑爹啊,于是把该段代码翻译成java色织完全ok了
翻译代码如下:
这样色斑图颜色也没问题了,第一次用arcgis服务和kml文件完成了arcgis与百度地图的结合,其他地图应当也是一样,完了再试试别的,欢迎指正