ArcGIS API for JS 测量线长(各折线段)

时间:2023-03-09 13:07:23
ArcGIS API for JS 测量线长(各折线段)

这里测量长度主要分为两个方面,一个是在绘制长折线段时,不仅需要显示总线段的长度,还要在各线段的中间显示各折线段的长度;另一个则是在绘制多边形时,不仅需要显示多边形的面积,还需要在各边的中间显示线段长。
前提:在每次绘制图形的时候,都要消除图层上已有的图形,那么则需要clear()图层。此处的clear()为地图的图像清除。如下:
     this.map.graphics.clear();// 清除了地图的图像,使其无法访问到GraphicsLayer
     this._refreshGraphics;
这里我所面对的问题有两个,因为菜单栏中包括有两个工具——线、面,因此在每次绘制之后需要再次更新图层。方法如下:
   _refreshGraphics: function () {
       // 此处需要将绘制的Layer设置和面积绘制的Layer相同,不然在长度测量完之后,打开面积测量时,绘制的面无法消除
      this._regionGraphics = this.map.getLayer('regionGraphics');
      if (this._regionGraphics) {
           this._regionGraphics.clear();
      } else {
          this._regionGraphics = new GraphicsLayer({id: 'regionGraphics'});
          this.map.addLayer(this._regionGraphics);
       }
   }
1、测量折线段的长度
情况一: 如果仅仅是计算某一个线段的话(不包括内部折线段的长度),那么是比较简单的可以直接利用ArcGIS API for JavaScript中提供的方法来做,如下:
postCreate: function(){
      this._lengthMeasure();
},
_lengthMeasure: function () {
     this.toolbar.activate(Draw.POLYLINE);
     this.drawEnd = this.toolbar.on("draw-end", lang.hitch(this, this._getLengthOrArea));
     this.geometryService = esriConfig.defaults.geometryService;
     this.geometryService.on("lengths-complete", lang.hitch(this, this.outputLength));
},
outputLength: function (evtObj) {
    var result = evtObj.result;
    //设置总长度样式
   var textSymbol = new TextSymbol("距离:" + result.lengths[0] + "米").setColor(
   // 需要将setAngle中的数值设为0,才能使Font水平显示
     new Color([255, 0, 0])).setAlign(Font.ALIGN_MIDDLE).setAngle(0).setFont(
     new Font("12pt").setWeight(Font.WEIGHT_BOLD));
     var graphic = new Graphic(new Point(this.drawResult.geometry.paths[0][0][0], this.drawResult.geometry.paths[0][0][1], this.drawResult.geometry.spatialReference), textSymbol);
     this.map.graphics.add(graphic);
},
_getLengthOrArea: function (result) {
    this.drawResult = result;
    var symbol;
    symbol = new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID, new Color([0, 0, 0]), 2);
   //设置样式
   var graphic = new Graphic(result.geometry, symbol);
   this._regionGraphics.add(graphic);
   //this.map.graphics.add(graphic);
   //如果为线类型就进行lengths距离测算
    if (result.geometry.type == "polyline") {
         if(result.geometry.paths[0].length > 2) {
            var lengthParams = new LengthsParameters();
            lengthParams.polylines = [result.geometry];
            lengthParams.lengthUnit = GeometryService.UNIT_METER;
            lengthParams.geodesic = true;
           this.geometryService.lengths(lengthParams);
          }
    this.toolbar.deactivate();
}
这样既可通过ArcGIS API for JavaScript提供的方法计算出总的长度了。那么我在现实需求中则需要显示每条线段的值,具体做法如下:
postCreate: function(){
      this._lengthMeasure();
},
_lengthMeasure: function () {
    this.toolbar.activate(Draw.POLYLINE);
    this.drawEnd = this.toolbar.on("draw-end", lang.hitch(this, this._getLengthOrArea));
    this.geometryService = esriConfig.defaults.geometryService;
    // 这里需要改成map的click事件监听,并且不能出现lengths-complete,不然无法计算各线段的长度
    this.mapClickEvent = this.map.on('click', lang.hitch(this, this._mapClick));
},
_mapClick: function (object){
    this._arrMapPoints.push(object.mapPoint);
   if(this._arrMapPoints.length >= 2 ){ 
        var i = this._arrMapPoints.length-1;
       var polylineJson = {
      "paths":[[[this._arrMapPoints[i-1].x,this._arrMapPoints[i-1].y],[this._arrMapPoints[i].x,this._arrMapPoints[i].y]]],
      "spatialReference": distMap.spatialReference
     };
    var startX = this._arrMapPoints[i].x;
    var startY = this._arrMapPoints[i].y;
    var centerPoint = new Point(startX, startY , distMap.spatialReference);
    var polyline = new esri.geometry.Polyline(polylineJson);
   /*这里为调用的计算方法,因为不在一个js文件中,我会在最下面贴出来该方法,若不想拆开,可直接在下添加计算方法,这里的数组polyline就是传到下面的函数中的geometry*/
      geoServiceUtils.geometryLength(polyline).then(lang.hitch(this, function(data){
          this.outputPartLength(data, centerPoint);
      }))
   }
},
/**
* 各折线长度格式设置
* @private
*/
outputPartLength: function(result,centerPoint){
// 长度超过一千的,单位均显示为千米,且保留小数点后两位
     if(result.lengths[0] > 1000){
     var partLength = (result.lengths[0]/1000).toFixed(2);
     //设置各长度样式
     var textSymbol = new TextSymbol(partLength + '千米').setColor(
     // 需要将setAngle中的数值设为0,才能使Font水平显示
     new Color([0, 0, 255])).setAlign(Font.ALIGN_MIDDLE).setAngle(0).setFont(
     new Font('10pt').setWeight(Font.WEIGHT_BOLD));
     var graphic = new Graphic(centerPoint, textSymbol);
     this.map.graphics.add(graphic);
} else{
    // 长度不足一千米的,单位均显示为米,且保留小数点后两位
    var smallPartLength = result.lengths[0].toFixed(2);
   //设置各长度样式
   var textSymbol = new TextSymbol(smallPartLength + '米').setColor(
   // 需要将setAngle中的数值设为0,才能使Font水平显示
   new Color([0, 0, 255])).setAlign(Font.ALIGN_MIDDLE).setAngle(0).setFont(
   new Font('10pt').setWeight(Font.WEIGHT_BOLD));
   var graphic = new Graphic(centerPoint, textSymbol);
   this.map.graphics.add(graphic);
}
},
/**
* 总长度格式设置
* @private
*/
outputLength: function (result) {
    if(result.lengths[0] > 1000){
        var allLengrh = (result.lengths[0]/1000).toFixed(2);
        //设置总长度样式
        var textSymbol = new TextSymbol('总距离:' + allLengrh + '千米').setColor(
        // 需要将setAngle中的数值设为0,才能使Font水平显示
        new Color([255, 0, 0])).setAlign(Font.ALIGN_MIDDLE).setAngle(0).setFont(
        new Font('12pt').setWeight(Font.WEIGHT_BOLD));
        var graphic = new Graphic(new Point(this.drawResult.geometry.paths[0][0][0], this.drawResult.geometry.paths[0][0][1], this.drawResult.geometry.spatialReference), textSymbol);
      this.map.graphics.add(graphic);
     } else{
         var smallAllLength = result.lengths[0].toFixed(2);
         //设置总长度样式
          var textSymbol = new TextSymbol('总距离:' + smallAllLength + '米').setColor(
          // 需要将setAngle中的数值设为0,才能使Font水平显示
          new Color([255, 0, 0])).setAlign(Font.ALIGN_MIDDLE).setAngle(0).setFont(
          new Font('12pt').setWeight(Font.WEIGHT_BOLD));
           var graphic = new Graphic(new Point(this.drawResult.geometry.paths[0][0][0], this.drawResult.geometry.paths[0][0][1], this.drawResult.geometry.spatialReference),                    textSymbol);
      this.map.graphics.add(graphic);
     }
    //设置总长度样式

this.mapClickEvent.remove();
    this.drawEnd.remove();
},
/**
* 画图完毕后计算距离或者面积
* @param result 画图完毕返回的画图对象
* @private
*/
_getLengthOrArea: function (result) {
this.drawResult = result;
var symbol;
symbol = new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID, new Color([0, 0, 0]), 2);
//设置样式
var graphic = new Graphic(result.geometry, symbol);
this._regionGraphics.add(graphic);
//进行总距离测算
if(result.geometry.type == 'polyline'){
geoServiceUtils.geometryLength(result.geometry).then(lang.hitch(this, function (data) {
this.outputLength(data);
}))
}
this.toolbar.deactivate();
},
/**
* 长度量测方法
* @param geometry
*/
mo.geometryLength = function (geometry) {
var geoService = esriConfig.defaults.geometryService;
var def = new Deferred();
// 计算总长度的值
if (geometry.paths[0].length > 2) {
var lengthParams = new LengthsParameters();
lengthParams.polylines = [geometry];
lengthParams.lengthUnit = GeometryService.UNIT_METER;
lengthParams.geodesic = true;
geoService.lengths(lengthParams, function (data) {
def.resolve(data);
}, function (err) {
def.reject(err);
});
} else {
// 计算各折线段的值
var lengthPartParams = new LengthsParameters();
lengthPartParams.polylines = [geometry];
lengthPartParams.lengthUnit = GeometryService.UNIT_METER;
lengthPartParams.geodesic = true;
geoService.lengths(lengthPartParams, function (data) {
def.resolve(data);
}, function (err) {
def.reject(err);
});
}
return def.promise;
}

至此,计算线段的长度以及计算一个线段各折线段的长度的方法已经得出,计算面的各线段长度和该方法一样,就不再赘述。