概述

买房的各位亲们不知是否留意过链家的"地图找房",这样的功能对于使用者来说,是非常方便的,大家可通过连接(https://bj.lianjia.com/ditu/)查看具体效果。鉴于此,本文结合该效果与功能,介绍在Arcgis4js中如何实现类似的效果。


功能效果

1、数据的聚合展示


2、地图高亮


3、聚合数据的钻取


4、列表展示



编码实现

1、数据的聚合展示

链家的实现是基于距离的一个聚合展示,在本实例中做了简化,聚合是通过后台统计查询实现的,其数据组织格式如下:


之后,在地图上做展示,关键代码如下:

                    $("#network").on("click",function(){
                    	for(var i=0;i<data.length;i++){
                    		var _d = data[i];
                    		var geometry = getGeomByWKT(_d.wkt);
                    		var pt = geometry.getCentroid();
                    		var sms = new SimpleMarkerSymbol(
				    							SimpleMarkerSymbol.STYLE_CIRCLE, 60,
				    							new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID,
											    	new Color([255,0,0]), 2),
											    new Color([255,0,0,0.5]));
											  var tsname = new TextSymbol(_d.counname).setOffset(0, 6).setColor(new Color([255,255,255])) ;  
											  var tsprice = new TextSymbol(_d.price.toFixed(2)+"万").setOffset(0, -7).setColor(new Color([255,255,255])); 
											  var tscount = new TextSymbol(_d.count+"套").setOffset(0, -22).setColor(new Color([255,255,255]));
											  var _gd = _d;
											  _d.index = i;
											  _gd.id="graphic"+i;
											  gLayer.add(new Graphic(pt, sms, _gd));
											  gLayer.add(new Graphic(pt, tsname,_d));
											  gLayer.add(new Graphic(pt, tsprice,_d));
											  gLayer.add(new Graphic(pt, tscount,_d));
                    	}
                    });

实现后效果入下:


2、地图高亮展示

地图高亮展示是鼠标经过聚合点时高亮展示该区域,代码如下:

                    gLayer.on("mouse-over",function(e){
                    	map.setMapCursor("pointer");
                    	var sms = new SimpleMarkerSymbol(
				    							SimpleMarkerSymbol.STYLE_CIRCLE, 60,
				    							new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID,
											    	new Color([0,0,255]), 2),
											    new Color([0,0,255,0.5]));
											var _zoneG = getGraphicById("graphic"+e.graphic.attributes.index);
											_zoneG.setSymbol(sms);
											gLayer.redraw();
											zLayer.clear();
									    var geometry = getGeomByWKT(e.graphic.attributes.wkt);
									    var sfs = new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID,
										    new SimpleLineSymbol(SimpleLineSymbol.STYLE_DASHDOT,
										    new Color([0,0,255]), 2),new Color([0,0,255,0.25])
										  );
									    var gfx = new Graphic(geometry,sfs);
				    					zLayer.add(gfx);
                    });
                    gLayer.on("mouse-out",function(e){
                    	map.setMapCursor("default");
                    	var sms = new SimpleMarkerSymbol(
				    							SimpleMarkerSymbol.STYLE_CIRCLE, 60,
				    							new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID,
											    	new Color([255,0,0]), 2),
											    new Color([255,0,0,0.5]));
											var _zoneG = getGraphicById("graphic"+e.graphic.attributes.index);
										  _zoneG.setSymbol(sms);
											gLayer.redraw();
											zLayer.clear();
                    })
实现后效果入下:


3、聚合数据的钻取与列表展示

点击聚合数据点,钻取数据,数据分别以地图和列表两种方式进行展示,关键代码如下:

										function addZoneData(attr){
											var geometry = getGeomByWKT(attr.wkt);
									    var extent = geometry.getExtent();
									    map.setExtent(extent);
									    var data = getZoneData(extent);
											$(".popup_main").show();
											var nsrlist = $("#nsrlist").html("");
											lLayer.clear();
											lLayer.show();
											var path = "m127,193l103,0l0,33l-56,0l-11,12l-11,-11l-25.00003,0.00002l0.00003,-34.00002z";
											var _sum = 0;
											for(var i=0;i<data.length;i++){
												var _d = data[i];
												var pt = new Point(_d.X, _d.Y, map.spatialReference);
											  var pms = new PictureMarkerSymbol("img/marker.png",24,24);
											  lLayer.add(new Graphic(pt, pms,_d));
											  var _li = $("<li/>").css("position","relative").appendTo(nsrlist);
											  _li.append('<div class="image"><img src="img/marker.png" /></div>');
											  _li.append('<div class="content">'+
											  	'<div class="item-tle">'+_d.NSRNAME+'</div>'+_d.NSRSUM+'万'+
											  	'</div>');
											  	_sum+=_d.NSRSUM;
											  _li.data("attr",_d);
											  _li.on("click",function(){
											  	var _attr = $(this).data("attr");
											  	showObjInfo(_attr);
											  });
											}
											$("#summary").html(attr.counname+"共有纳税人"+data.length+"人,共纳税"+_sum.toFixed(3)+"万元。")
											$("#block_close").on("click",function(){
												$(".popup_main").hide();
												lLayer.clear();
                   	 		map.infoWindow.hide();
											});
										}
实现效果如下:



上述实现完整代码如下:

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"/>
    <title>Simple Map</title>
    <link rel="stylesheet" href="http://jsapi.thinkgis.cn/esri/css/esri.css">
    <style>
      html, body, #map {
        height: 100%;
        width: 100%;
        margin: 0;
        padding: 0;
      }
      body {
        background-color: #FFF;
        overflow: hidden;
        font-family: "Trebuchet MS";
      }
      .info-content a{
      	float:right;
      }
      .popup_main{
      	border:1px solid #cdcdcd;
				z-index:1001;
				position:absolute;
				background:#fff;
				overflow:hidden;
				left:20px;
				top:100px;
				width:330px;
				display: none;
      }
      .popup_main .title {
				border-bottom:1px solid #dadada;
				height:25px;
				line-height:25px;
				font-size:12px;
				color:#4c4c4c;
				padding-left:7px;
			}
			.popup_main .summary {
				margin:2px;
				background: #ccc;
				padding: 8px;
				border-bottom:1px solid #ddd;
			}
			.popup_main .content {
				height:auto;
				padding: 8px;
				border-bottom:1px solid #ddd;
			}
			.popup_main ul{
				list-style: none;
				margin: -0px 0;
				overflow:hidden;
				overflow-y:auto;
				max-height: 500px;
			}
			.popup_main ul li {
				position: relative;
				margin-left: -40px;
				position: relative;
				border-bottom:1px solid #ddd;
				cursor: pointer;
				height: 50px;
			}
			.popup_main ul li:hover{
				background: #ccc;
			}
			.popup_main ul li .image{
				position:absolute;
				left:8px;
				top: 10px;
				height:30px;
				text-align:center;
				width:30px;
				line-height:15px;
			}
			.popup_main ul li .image img{
				height: 100%;
			}
			.popup_main ul li .content{
				    width: 85%;
				    float: right;
				    border: none;
			}
			.popup_main ul li .content div.item-tle{
				  font-size: 14px;
					color: #262626;
					font-weight: 800;
					overflow: hidden;
					text-overflow: ellipsis;
					line-height: 1;
			}
			.popup_main button{
		    position: absolute;
		    z-index: 50;
		    top: 7px;
		    right: 6px;
		    width: 12px;
		    height: 12px;
		    background: url(img/popup_close_15d2283.gif) no-repeat;
		    border: 0;
		    cursor: pointer;
		  }
    </style>    
    <script type="text/javascript">
	    dojoConfig = {
	      parseOnLoad: true,
	      packages: [{
	        name: 'tdlib',
	        location: this.location.pathname.replace(/\/[^/]+$/, "")+"/tdtlib"
	      }]
	    };
	  </script>
	<script src="http://jsapi.thinkgis.cn/init.js"></script>
	<script src="http://lzugis.d152.ptzygj.com/app/js/jquery/jquery-1.8.3.js"></script>
	<script src="terraformer/terraformer.js"></script>
  <script src="terraformer/terraformer-wkt-parser.js"></script>
  <script src="terraformer/terraformer-arcgis-parser.js"></script>
	<script src="data.js"></script>
    <script>
      var map;
        require([
            "esri/map",
            "tdlib/TDTTilesLayer",
            "esri/layers/GraphicsLayer",
            "esri/geometry/Point",
            "esri/geometry/Extent",
            "esri/geometry/Polyline",
            "esri/symbols/SimpleLineSymbol",
            "esri/symbols/SimpleMarkerSymbol",
            "esri/symbols/PictureMarkerSymbol",
            "esri/symbols/SimpleFillSymbol",
            "esri/symbols/TextSymbol",
            "esri/Color",
            "esri/geometry/jsonUtils",
            "esri/graphic",
             "esri/dijit/InfoWindow",
            "dojo/domReady!"],
                function(Map,
                     TDTTilesLayer,
                     GraphicsLayer,
                     Point,
                     Extent,
                Polyline,
                SimpleLineSymbol,
                SimpleMarkerSymbol,
                PictureMarkerSymbol,
                SimpleFillSymbol,
                TextSymbol,
                Color,
                geometryJsonUtils,
                Graphic,InfoWindow)
                {
                   	map = new Map("map", { 
											logo: false,
											center: [116.43228121152976, 40.20122178384614], // longitude, latitude
									    zoom: 7
										});
								    var vec_c = new TDTTilesLayer("vec")
								    map.addLayer(vec_c);
								    var zLayer = new GraphicsLayer();
                    map.addLayer(zLayer);
                    var gLayer = new GraphicsLayer();
                    map.addLayer(gLayer);
                    var lLayer = new GraphicsLayer();
                    map.addLayer(lLayer);
                    
                    lLayer.on("mouse-over",function(e){
                    	map.setMapCursor("pointer");
                    })
                    lLayer.on("mouse-out",function(e){
                    	map.setMapCursor("default");
                    })
                    lLayer.on("click",function(e){
                    	var attr = e.graphic.attributes;
                    	if(attr){
                    		showObjInfo(attr);
                    	}
                    })
                    
                   	 map.on("zoom-end",function(anchor,extent,level,zoomFactor){
                   	 	if(map.getZoom()<8){
                   	 		gLayer.show();
                   	 		lLayer.hide();
                   	 		map.infoWindow.hide();
                   	 	};
                   	 });
                    
                    $("#network").on("click",function(){
                    	for(var i=0;i<data.length;i++){
                    		var _d = data[i];
                    		var geometry = getGeomByWKT(_d.wkt);
                    		var pt = geometry.getCentroid();
                    		var sms = new SimpleMarkerSymbol(
				    							SimpleMarkerSymbol.STYLE_CIRCLE, 60,
				    							new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID,
											    	new Color([255,0,0]), 2),
											    new Color([255,0,0,0.5]));
											  var tsname = new TextSymbol(_d.counname).setOffset(0, 6).setColor(new Color([255,255,255])) ;  
											  var tsprice = new TextSymbol(_d.price.toFixed(2)+"万").setOffset(0, -7).setColor(new Color([255,255,255])); 
											  var tscount = new TextSymbol(_d.count+"套").setOffset(0, -22).setColor(new Color([255,255,255]));
											  var _gd = _d;
											  _d.index = i;
											  _gd.id="graphic"+i;
											  gLayer.add(new Graphic(pt, sms, _gd));
											  gLayer.add(new Graphic(pt, tsname,_d));
											  gLayer.add(new Graphic(pt, tsprice,_d));
											  gLayer.add(new Graphic(pt, tscount,_d));
                    	}
                    });
                    
                    gLayer.on("mouse-over",function(e){
                    	map.setMapCursor("pointer");
                    	var sms = new SimpleMarkerSymbol(
				    							SimpleMarkerSymbol.STYLE_CIRCLE, 60,
				    							new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID,
											    	new Color([0,0,255]), 2),
											    new Color([0,0,255,0.5]));
											var _zoneG = getGraphicById("graphic"+e.graphic.attributes.index);
											_zoneG.setSymbol(sms);
											gLayer.redraw();
											zLayer.clear();
									    var geometry = getGeomByWKT(e.graphic.attributes.wkt);
									    var sfs = new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID,
										    new SimpleLineSymbol(SimpleLineSymbol.STYLE_DASHDOT,
										    new Color([0,0,255]), 2),new Color([0,0,255,0.25])
										  );
									    var gfx = new Graphic(geometry,sfs);
				    					zLayer.add(gfx);
                    });
                    gLayer.on("mouse-out",function(e){
                    	map.setMapCursor("default");
                    	var sms = new SimpleMarkerSymbol(
				    							SimpleMarkerSymbol.STYLE_CIRCLE, 60,
				    							new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID,
											    	new Color([255,0,0]), 2),
											    new Color([255,0,0,0.5]));
											var _zoneG = getGraphicById("graphic"+e.graphic.attributes.index);
										  _zoneG.setSymbol(sms);
											gLayer.redraw();
											zLayer.clear();
                    })
                    gLayer.on("click",function(e){
                    	gLayer.hide();
									    addZoneData(e.graphic.attributes);
                    });
                    function getGraphicById(id){
                    	var g = null;
                    	var graphics = gLayer.graphics;
                    	for(var i=0,len = graphics.length;i<len;i++){
                    		var graphic = graphics[i];
                    		if(graphic.attributes.id===id){
                    			g = graphic;
                    			break;
                    		}
                    	}
                    	return g;
                    }
                    function getGeomByWKT(wkt){
                    	var primitive = Terraformer.WKT.parse(wkt);
									    var arcgis = Terraformer.ArcGIS.convert(primitive);
									    return geometryJsonUtils.fromJson(arcgis);
                    }
                    function getZoneData(extent){
                    	var data = [];
                    	for(var i=0;i<10;i++){
                    		var nusnum = GetRandomNum(10,100).toFixed(3);
                    		nusnum = parseFloat(nusnum);
                    		data.push({
                    			X:GetRandomNum(extent.xmin,extent.xmax),
                    			Y:GetRandomNum(extent.ymin,extent.ymax),
                    			NSRNAME:"name"+i,
                    			NSRSUM:nusnum,
                    			URL:"#"
                    		});
                    	}
                    	return data;
                    }
										function addZoneData(attr){
											var geometry = getGeomByWKT(attr.wkt);
									    var extent = geometry.getExtent();
									    map.setExtent(extent);
									    var data = getZoneData(extent);
											$(".popup_main").show();
											var nsrlist = $("#nsrlist").html("");
											lLayer.clear();
											lLayer.show();
											var path = "m127,193l103,0l0,33l-56,0l-11,12l-11,-11l-25.00003,0.00002l0.00003,-34.00002z";
											var _sum = 0;
											for(var i=0;i<data.length;i++){
												var _d = data[i];
												var pt = new Point(_d.X, _d.Y, map.spatialReference);
											  var pms = new PictureMarkerSymbol("img/marker.png",24,24);
											  lLayer.add(new Graphic(pt, pms,_d));
											  var _li = $("<li/>").css("position","relative").appendTo(nsrlist);
											  _li.append('<div class="image"><img src="img/marker.png" /></div>');
											  _li.append('<div class="content">'+
											  	'<div class="item-tle">'+_d.NSRNAME+'</div>'+_d.NSRSUM+'万'+
											  	'</div>');
											  	_sum+=_d.NSRSUM;
											  _li.data("attr",_d);
											  _li.on("click",function(){
											  	var _attr = $(this).data("attr");
											  	showObjInfo(_attr);
											  });
											}
											$("#summary").html(attr.counname+"共有纳税人"+data.length+"人,共纳税"+_sum.toFixed(3)+"万元。")
											$("#block_close").on("click",function(){
												$(".popup_main").hide();
												lLayer.clear();
                   	 		map.infoWindow.hide();
											});
										}
										
										function showObjInfo(data){
											var location = new Point(data.X, data.Y, map.spatialReference);
											map.infoWindow.setTitle(data.NSRNAME);
											var content= $("<div/>").addClass("info-content");
											content.append("<b>纳税人名称:</b>"+data.NSRNAME);
											content.append("<br/><b>纳税人金额:</b>"+data.NSRSUM);
											content.append("<br/><a href="+data.URL+">详细信息>></a>");
											map.infoWindow.setContent(content[0]);
											map.infoWindow.show(location, InfoWindow.ANCHOR_UPPERRIGHT);
											map.centerAt(location);
										}
                });
			function GetRandomNum(min, max){
            var r = Math.random()*(max - min);
            var re=r+min;
            return re;
      }
    </script>
  </head>
  <body>
    <div id="map">
    	<div class="popup_main">
    		<div class="title">列表</div>
    		<div class="summary" id="summary">温泉镇共有纳税人100人,共纳税100万元。</div>
    		<ul id="nsrlist">
    		</ul>
    		<button id="block_close" title="关闭"></button>
    	</div>
    	<button style="position:absolute;top:10px;right:10px;z-index: 99;" id="network">network</button>
    </div>
  </body>
</html>

---------------------------------------------------------------------------------------------------------------

技术博客

CSDN:http://blog.csdn.NET/gisshixisheng

博客园:http://www.cnblogs.com/lzugis/

在线教程

http://edu.csdn.Net/course/detail/799

Github

https://github.com/lzugis/

联系方式

q       q:1004740957

e-mail:niujp08@qq.com

公众号:lzugis15

Q Q 群:452117357(webgis)

             337469080(Android)


posted on 2017-04-30 13:57  LZU-GIS  阅读(252)  评论(0编辑  收藏  举报