概述
买房的各位亲们不知是否留意过链家的"地图找房",这样的功能对于使用者来说,是非常方便的,大家可通过连接(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));
}
});
实现后效果入下:
地图高亮展示是鼠标经过聚合点时高亮展示该区域,代码如下:
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)