对于开发webgis来说,无论做什么样的项目,都有一些基础的功能,比如地图初始化,地图放大缩小、加载图层、绘制图形、要素查询、添加点、线、面等。为了方便日后开发,特意对这些功能进行了封装,方便以后进行扩展和提升工具效率。下面主要从地图初始化、添加图层、绘制、查询、添加图形等方面来介绍一下代码的封装。
1.创建封装类
基于js的特性,可以使用面向对象和原型的思想来封装工具类,首先创建一个JTMapKit
类用于封装属性和方法,具体代码如下所示:
function JTMapKit(option) {
this.mapOption = {};
this._init(option || {});
//默认点符号
this.pointSymbol = {
type: "simple-marker",
style: "square",
color: "red",
size: "16px",
outline: {
color: [255, 255, 0],
width: 3
}
}
//默认线符号
this.lineSymbol = {
type: "simple-line",
color: [4, 90, 141],
width: 3,
cap: "round",
join: "round"
}
//默认面符号
this.fillSymbol = {
type: "simple-fill",
color: "purple",
style: "solid",
outline: {
color: "white",
width: 1
}
}
this.isDrawing = false;//正在绘制中,用于控制多点绘制
}
在类中主要添加了如下属性:
_init
:用于初始化地图和一些参数。
mapOption
:用于保存地图的一些属性。
pointSymbol
:用于创建默认的点符号。
lineSymbol
:用于创建默认的线符号。
fillSymbol
:用于创建默认的面符号。
isDrawing
:标识正在绘制中,用于控制多点绘制
然后再通过一个extend
方法来合并原型中添加的方法,如下所示:
JTMapKit.prototype.extend = function (option) {
for (key in option) {
JTMapKit.prototype[key] = option[key];
}
}
2.地图初始化
地图初始化主要是对地图加载、地图基本操作的封装,首先通过调用_init
来进行初始化,_init
方法有一个option
参数,该参数主要用于设置地图的选择器、加载完成后的回调、地图类型、底图、中心点,全图范围等等。具体如下所示:
JTMapKit.prototype.extend({
//初始化配置信息
_init: function (option) {
this.selector = option.selector || 'map';//地图选择器
this.onMapReady = option.onMapReady;//地图加载完后处理
this.onViewReady = option.onViewReady;//mapView加载完成后添加底图
this.mapType = option.mapType || '2d';//地图类型,2d,3d
//地图相关参数
this.mapOption.basemap = option.basemap;//底图
this.mapOption.center = option.center;//中心点
this.mapOption.extent = option.extent;//全图
if (this.mapType.toLocaleLowerCase() === '3d') {
} else {
this._init2dMap();
}
},
//初始化地图
_init2dMap: function () {
var self = this;
require(["esri/Map", "esri/views/MapView"], function (Map, MapView) {
self.map = new Map({
basemap: self.mapOption.basemap
});
self.mapView = new MapView({
container: self.selector,
map: self.map,
})
if (self.onViewReady) {
self.onViewReady(self.mapView);
}
self.mapView.when(function () {
//地图加载完成
if (self.onMapReady) {
self.onMapReady(self.map, self.mapView);
}
}, function (error) {
console.log("地图加载失败", error);
});
});
},
setExtent: function (extent) {
this.mapView.extent = extent;
},
setZoom: function (zoom) {
this.mapView.zoom = zoom;
},
setCenter: function (center) {
this.mapView.center = center;
},
setScale: function (scale) {
this.mapView.scale = scale;
},
// 隐藏放大缩小的工具条
hidenZoomToolBar: function () {
this.mapView.ui.remove("zoom");
},
//隐藏底部的logo
hidenLogo: function () {
this.mapView.ui.remove("attribution");
},
//放大
zoomIn:function () {
var self = this;
require(["esri/widgets/Zoom"], function(Zoom) {
var zoom = new Zoom({
view: self.mapView
});
zoom.zoomIn();
});
},
//缩小
zoomOut:function () {
var self = this;
require(["esri/widgets/Zoom"], function(Zoom) {
var zoom = new Zoom({
view: self.mapView
});
zoom.zoomOut();
});
}
})
常用方法
setExtent
:用于设置地图的全图范围。
setZoom
:用于设置地图的缩放级别。
setCenter
:用于设置地图的中心点。
setScale
:用于设置地图的缩放比例尺。
hidenZoomToolBar
:用于隐藏地图上的放大缩小组件。
hidenLogo
:用于隐藏地图上面的logo。
zoomIn
:用于放大地图。
zoomOut
:用于缩小地图。
3.添加图层
主要是用于方便添加图层,主要包括添加动态图层、添加要素图层、添加titleLayer,其它的等以后需要用到时再慢慢补充。方法中的option
参数主要用于设置图层相关的属性、比如地图的url,id,title,visible等属性。
JTMapKit.prototype.extend(
{
//添加动态图层
addDynamicLayer: function (option) {
if (!option) {
return
}
var self = this;
require(["esri/layers/MapImageLayer"], function (MapImageLayer) {
var layer = new MapImageLayer(option);
self.map.layers.add(layer);
return layer;
});
},
//添加要素图层
addFeatureLayer: function (option) {
if (!option) {
return
}
option.outFields ? option.outFields : ["*"];
var self = this;
require(["esri/layers/FeatureLayer"], function (FeatureLayer) {
var layer = new FeatureLayer(option);
self.map.layers.add(layer);
return layer;
});
},
//添加titleLayer
addTileLayer: function (option) {
if (!option) {
return
}
var self = this;
require(["esri/layers/TileLayer"], function (TileLayer) {
var layer = new TileLayer(option);
self.map.layers.add(layer);
return layer;
});
}
}
)
4.绘制图形
绘制图形主要包括绘制点、线、面、圆、矩形等。将所有绘制的方法进行了封装、在html中调用的时候,只需要传递图形符号就行。具体的代码实现如下所示:
JTMapKit.prototype.extend({
_draw:function (type,option) {
var self = this;
require([
"esri/views/draw/Draw",
"esri/layers/GraphicsLayer",
"esri/Graphic"],
function (Draw, GraphicsLayer, Graphic) {
self.clearGraphic();
if (!self.graphicsLayer) {
self.graphicsLayer = new GraphicsLayer();
self.map.layers.add(self.graphicsLayer);
}
var draw = new Draw({
view: self.mapView
});
var action = draw.create(type);
option.type = type;
//添加点
action.on("vertex-add", function (evt) {
self._drawActionHandler(evt,option,Graphic);
});
//绘制结束
action.on("draw-complete", function (evt) {
self._drawActionHandler(evt,option,Graphic);
});
//删除点
action.on("vertex-remove", function (evt) {
self._drawActionHandler(evt,option,Graphic);
});
action.on("cursor-update",function (evt) {
if(type === 'circle'){
self._drawActionHandler(evt,option,Graphic);
}else if(type === 'rectangle'){
self._drawActionHandler(evt,option,Graphic);
}
})
if(type === 'multipoint'){
self.mapView.on('click',function (evt) {
self._addMultipoint(evt,option,Graphic)
})
}
});
},
//绘制处理事件
_drawActionHandler(evt,option,Graphic){
if(option.type === 'circle'){
this._drawCircleActionHandler(evt,option,Graphic);
return;
}else if(option.type === 'rectangle'){
this._drawRectangleActionHandler(evt,option,Graphic);
return;
}
var geometry;
if(evt.coordinates){//绘制单个点时获取的是coordinates
var coordinates = evt.coordinates;
geometry = {
type: "point",
x: coordinates[0],
y: coordinates[1],
spatialReference: this.mapView.spatialReference
};
}else if(evt.vertices){
var vertices = evt.vertices;
var type = option.type;
geometry = {
spatialReference: this.mapView.spatialReference
};
//多点
if(type === 'multipoint'){
this.isDrawing = false;
geometry.points = vertices;
geometry.type = "multipoint";
}else if(type === 'polyline'){
geometry.paths = vertices;
geometry.type = "polyline";
}else{
geometry.rings = vertices;
geometry.type = "polygon";
}
}
var graphic = new Graphic({
geometry: geometry,
symbol: option.symbol
});
this.graphicsLayer.add(graphic);
},
//绘制圆
_drawCircleActionHandler(evt,option,Graphic){
var self = this;
require(["esri/geometry/Circle",
"esri/geometry/Point"], function(Circle,Point) {
var vertices = evt.vertices;
if(vertices.length<2){
return
}
self.graphicsLayer.removeAll();
var center=new Point({
hasZ: false,
hasM: false,
x:vertices[0][0],
y:vertices[0][1],
spatialReference: self.mapView.spatialReference
});
var radius=center.distance(new Point({
hasZ: false,
hasM: false,
x:vertices[1][0],
y:vertices[1][1],
spatialReference: self.mapView.spatialReference
}));
var graphic = new Graphic({
geometry: new Circle({
hasZ: false,
hasM: false,
center:center,
radius:radius,
spatialReference: self.mapView.spatialReference
}),
symbol: option.symbol
});
self.graphicsLayer.add(graphic);
});
},
//绘制矩形
_drawRectangleActionHandler(evt,option,Graphic){
var self = this;
require(["esri/geometry/Circle",
"esri/geometry/Polygon"], function(Circle,Polygon) {
//获取所有顶点
var vertices = evt.vertices;
if(vertices.length<2){
return
}
var rings=[vertices[0],[vertices[0][0],vertices[1][1]],vertices[1],[vertices[1][0],vertices[0][1]]];
self.graphicsLayer.removeAll();
var graphic = new Graphic({
geometry: new Polygon({
hasZ: false,
hasM: false,
rings: [rings],
spatialReference: self.mapView.spatialReference
}),
symbol: option.symbol
});
self.graphicsLayer.add(graphic);
});
},
//绘制多个点
_addMultipoint:function(evt,option,Graphic){
if(this.isDrawing){
var graphic = new Graphic({
geometry: evt.mapPoint,
symbol: option.symbol
});
this.graphicsLayer.add(graphic);
}
},
//绘制单个点
drawPoint:function(option){
var options = option || {};
if(!options.symbol){
options.symbol = this.pointSymbol;
}
this._draw('point',options);
},
//绘制多个点
drawMultiPoint:function(option){
this.isDrawing = true;
var options = option || {};
if(!options.symbol){
options.symbol = this.pointSymbol;
}
this._draw('multipoint',options);
},
//绘制线
drawPolyline:function(option){
var options = option || {};
if(!options.symbol){
options.symbol = this.lineSymbol;
}
this._draw('polyline',options);
},
//绘制多边形
drawPolygon:function(option){
var options = option || {};
if(!options.symbol){
options.symbol = this.fillSymbol;
}
this._draw('polygon',options);
},
//绘制矩形
drawRectangle:function(option){
var options = option || {};
if(!options.symbol){
options.symbol = this.fillSymbol;
}
this._draw('rectangle',options);
},
//绘制圆
drawCircle:function(option){
var options = option || {};
if(!options.symbol){
options.symbol = this.fillSymbol;
}
this._draw('circle',options);
},
//清空绘制图层
clearGraphic:function () {
if(this.graphicsLayer){
this.graphicsLayer.removeAll();
}
}
})
绘制图形的大致思路是先实例Draw
对象,然后再根据绘制的类型来调用create
方法,然后再监听vertex-add
,draw-complete
,vertex-remove
,cursor-update
等事件来生成geometry
对象,再创建Graphic
添加到图层中。
5.要素查询
图形要素查询主要使用QueryTask
和Query
来完成,首先用QueryTask
创建一个查询任务,QueryTask
可以设置查询的图层地址,然后再创建一个Query
对象,来设置查询的条件,是否返回图形、返回的字段信息等 。查询数据后,可以将要素添加到地图上进行高亮显示。具体代码如下所示:
JTMapKit.prototype.extend({
/*
* 图层查询
* */
query:function (uri,where,callback) {
var self = this;
require([
"esri/tasks/QueryTask",
"esri/tasks/support/Query"],
function(QueryTask,Query){
var queryTask = new QueryTask(uri);
var query = new Query();
query.outSpatialReference = self.mapView.spatialReference;
query.returnGeometry = true;
query.outFields = ["*"];
query.where = where;
queryTask.execute(query).then(function(results){
if(callback){
callback(results);
}
})
})
},
addFeatures2Map:function (features,options) {
options = options || {};
options.symbol = options.symbol || {};
var self = this;
require([
"esri/layers/GraphicsLayer",
"esri/Graphic"],
function ( GraphicsLayer, Graphic){
if (!self.featureLayer) {
self.featureLayer = new GraphicsLayer();
self.map.layers.add(self.featureLayer);
}else{
this.featureLayer.removeAll();
}
if (features.length === 0) return;
for (var i = 0; i
6.添加点、线、面
添加点、线、面的方法跟绘制图形的方法差不多,只是这里是直接通过传递的坐标进行绘制,具体实现代码如下所示:
JTMapKit.prototype.extend({
//添加点
addPoint:function (option) {
option.type = 'point';
this._addTempLayer(option)
},
//添加线
addLine:function (option) {
option.type = 'polyline';
this._addTempLayer(option)
},
//添加面
addPolygon:function (option) {
option.type = 'polygon';
this._addTempLayer(option)
},
//添加临时图层,用于添加点、线、面
_addTempLayer:function (option) {
var self = this;
require(["esri/layers/GraphicsLayer","esri/Graphic"], function(GraphicsLayer,Graphic) {
if (!self.tempLayer) {
self.tempLayer = new GraphicsLayer();
self.map.layers.add(self.tempLayer);
}
var type = option.type,symbol;
var geometry = {
type: type,
spatialReference: self.mapView.spatialReference
};
option.symbol = option.symbol || {};
if(type === 'point'){
geometry.longitude = option.x;
geometry.latitude = option.y;
symbol = option.symbol.point || self.pointSymbol;
}else if(type === 'polyline'){
geometry.paths = option.paths;
symbol = option.symbol.polyline || self.lineSymbol;
}else if(type === 'polygon'){
geometry.rings = option.rings;
symbol = option.symbol.polygon || self.fillSymbol;
}
var graphic = new Graphic({
geometry: geometry,
symbol: symbol
});
self.tempLayer.add(graphic);
});
},
clearTempLayer:function () {
if(this.tempLayer){
this.tempLayer.removeAll();
}
}
})
个人博客