ArcGIS For JS 距离与面积量算的三种方法

在用ArcGIS For JS开发地图过程中,距离与面积的量算功能是比较常用的,下面我们来看看实现量算功能的三种方法。

1.GeometryService

GeometryService是ArcGIS For JS提供的一种服务,需要依赖ArcGIS发布的几何服务

 (1)定义geometryService

                    var geometryService = new GeometryService("https://utility.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer");
             dojo.connect(geometryService, "onLengthsComplete", this.lengthsCompleteHandler);
             dojo.connect(geometryService, "onSimplifyComplete",this.geometryService_simplifyCompleteHandler);

(2)在drawTool的draw-end事件中添加代码

距离量算

              var drawLine = new esri.geometry.Polyline(event.geometry);
               var lengthParams = new esri.tasks.LengthsParameters();
              lengthParams.polylines = [drawLine];
              lengthParams.lengthUnit = esri.tasks.GeometryService.UNIT_METER;
              lengthParams.geodesic = true;
              lengthParams.polylines[0].spatialReference = new esri.SpatialReference(4490);
              geometryService.lengths(lengthParams);
                     latestEndpoint = drawLine.paths[0][0];

              //把线添加到地图
              var g = new Graphic(event.geometry, lengthLine);
              myGraphicsLayer2.add(g);

面积量算

                    addPolygonToMap(event.geometry);
               projectPolygon(event.geometry);

(3)结果处理

距离

            lengthsCompleteHandler: function (event) {
                var dist = event.lengths[0];
                var myAttributes = {};
                var lengthSymbol = new TextSymbol().setColor(myUtity.GetColorUint("00ff00", 1)).setAlign(Font.ALIGN_START).setFont(new Font("14px").setWeight(Font.WEIGHT_BOLD));
                if (dist < 3000) {
                    lengthSymbol.setText("长度为:" + dist.toFixed(2) + "米");
                } else {
                    lengthSymbol.setText("长度为:" + parseFloat(dist / 1000).toFixed(2) + "千米");
                }
                var CurX = latestEndpoint[0];
                var CurY = latestEndpoint[1];
                var CurPos = new Point(CurX, CurY, map.spatialReference);
                var g = new Graphic(CurPos, lengthSymbol, myAttributes);
                myGraphicsLayer2.add(g);
            },

面积

//向地图添加多边形   面积测量
            addPolygonToMap: function (polygon) {
                if (V == "mj") {
                    var newGraphic = new Graphic(polygon, myfind);
                    myGraphicsLayer2.add(newGraphic);
                }
            },
            geometryService_simplifyCompleteHandler: function (event) {
                if (event) {
                    var polygon = event[0];
                    this.addPolygonToMap(polygon);
                    this.projectPolygon(polygon);
                }
            },
            //面积测量
            projectPolygon: function (polygon) {
                var projectParameters = new ProjectParameters();
                projectParameters.geometries = [polygon];
                projectParameters.outSR = new SpatialReference(54034);
                geometryService.project(projectParameters, this.project_resultHandler, this.project_faultHandler);
            },
            project_resultHandler: function (result) {

                if (result) {
                    var polygon = result[0];
                    var areasAndLengthsParameters = new AreasAndLengthsParameters();
                    areasAndLengthsParameters.areaUnit = GeometryService.UNIT_SQUARE_KILOMETERS; //单位
                    areasAndLengthsParameters.lengthUnit = GeometryService.UNIT_KILOMETER; //单位
                    areasAndLengthsParameters.polygons = [polygon];
                    geometryService.areasAndLengths(areasAndLengthsParameters, areasAndLengths_resultHandler, areasAndLengths_faultHandler);
                }
            },
            project_faultHandler: function (fault) {
                alert("project_faultHandler:" + fault);
            },
            areasAndLengths_resultHandler: function (event) {
                var areaTextSymbol = new TextSymbol().setColor(GetColorUint("41423A", 1)).setAlign(Font.ALIGN_START).setFont(new Font("14px").setWeight(Font.WEIGHT_BOLD));
                var area = event.areas[0];
                if (parseInt(area) < 10) {
                    areaTextSymbol.setText(parseInt((parseFloat(area) * 1500)).toFixed(2) + "亩");
                }
                else {
                    areaTextSymbol.setText(parseFloat(area).toFixed(2) + "平方千米");
                }
                var CurPos = measuregeometry.getCentroid();
                var x = "", y = "";
                for (var i = 0; i < measuregeometry.rings[0].length; i++) {
                    x = x + measuregeometry.rings[0][i][0] + ",";
                    y = y + measuregeometry.rings[0][i][1] + ",";

                }
                var g = new Graphic(CurPos);
                g.setSymbol(areaTextSymbol);
                var pmsTextBg = new PictureMarkerSymbol(myConfig.ServerUrl + 'images/normal_btn_bg.png', 120, 18);
                pmsTextBg.setWidth(parseFloat(area).toFixed(2).length * 10 + (areaTextSymbol.text.length - parseFloat(area).toFixed(2).length) * 14);
                pmsTextBg.setOffset(0, 5);
                pmsTextBg.setColor(myUtity.GetColorUint("ffffff", 0.1));
                var bgGraphic = new Graphic(CurPos, pmsTextBg);
                myGraphicsLayer2.add(bgGraphic);
                myGraphicsLayer2.add(g);
            },
            areasAndLengths_faultHandler: function (fault) {
                alert("areasAndLengths_faultHandler:" + fault);
            }

2.geodesicUtils

geodesicUtils也是ArcGIS For JS 提供的,但不依赖ArcGIS发布的几何服务

距离

             projectPolyline: function (polyline) {
                var length = this.getLength(polyline)[0];
                var lengthSymbol = new TextSymbol().setColor(getColorUint("00ff00", 1)).setAlign(Font.ALIGN_START).setFont(new Font("14px").setWeight(Font.WEIGHT_BOLD));
                if (length < 3000) {
                    lengthSymbol.setText("长度为:" + length.toFixed(2) + "米");
                } else {
                    lengthSymbol.setText("长度为:" + parseFloat(length / 1000).toFixed(2) + "千米");
                }
                var CurX = polyline.paths[0][0][0];
                var CurY = polyline.paths[0][0][1];
                var CurPos = new Point(CurX, CurY, map.spatialReference);
                var g = new Graphic(CurPos, lengthSymbol);
                myGraphicsLayer2.add(g);
            },
            getLength: function (polyline) {
                var length = geodesicUtils.geodesicLengths([polyline], units.METERS);
                return length;
            }

面积

  //面积测量
            projectPolygon: function (polygon) {
                var area = this.getArea(polygon);
                var areaTextSymbol = new TextSymbol().setColor(myUtity.getColorUint("41423A", 1)).setAlign(Font.ALIGN_START).setFont(new Font("14px").setWeight(Font.WEIGHT_BOLD));
                if (parseInt(area) < 10) {
                    areaTextSymbol.setText(parseInt((parseFloat(area) * 1500)).toFixed(2) + "亩");
                }
                else {
                    areaTextSymbol.setText(parseFloat(area).toFixed(2) + "平方千米");
                }
                var CurPos = measuregeometry.getCentroid();
                var x = "", y = "";
                for (var i = 0; i < measuregeometry.rings[0].length; i++) {
                    x = x + measuregeometry.rings[0][i][0] + ",";
                    y = y + measuregeometry.rings[0][i][1] + ",";

                }
                var g = new Graphic(CurPos);
                g.setSymbol(areaTextSymbol);
                var pmsTextBg = new PictureMarkerSymbol(myConfig.ServerUrl + 'images/normal_btn_bg.png', 120, 18);
                pmsTextBg.setWidth(parseFloat(area).toFixed(2).length * 10 + (areaTextSymbol.text.length - parseFloat(area).toFixed(2).length) * 14);
                pmsTextBg.setOffset(0, 5);
                pmsTextBg.setColor(myUtity.getColorUint("ffffff", 0.1));
                var bgGraphic = new Graphic(CurPos, pmsTextBg);
                myGraphicsLayer2.add(bgGraphic);
                myGraphicsLayer2.add(g);
            },
            getArea: function (polygon) {
                var area = geodesicUtils.geodesicAreas([polygon], units.SQUARE_KILOMETERS);
                return area;
            },

3.自定义函数

通过参考OpenLayer的源码,自定义距离与面积的量算函数

距离

           getLength: function (len) {
                var length = 0;
                for (var i = 0, ii = len.paths.length; i < ii; i++) {
                    length += getLength_(len.paths[i]);
                }
                return length;
            },
            getLength_: function (ring) {
                var length = 0;
                for (i = 0, ii = ring.length; i < ii - 1; ++i) {
                    length += getDistance_(ring[i], ring[i + 1]);
                }
                return length;
            },
            getDistance_: function (c1, c2) {
                var radius = 6371008.8;
                var lat1 =toRadians(c1[1]);
                var lat2 = toRadians(c2[1]);
                var deltaLatBy2 = (lat2 - lat1) / 2;
                var deltaLonBy2 = toRadians(c2[0] - c1[0]) / 2;
                var a = Math.sin(deltaLatBy2) * Math.sin(deltaLatBy2) + Math.sin(deltaLonBy2) * Math.sin(deltaLonBy2) * Math.cos(lat1) * Math.cos(lat2);
                return 2 * radius * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
            },
            toRadians: function (angleInDegrees) {
                return angleInDegrees * Math.PI / 180;
            }
面积

            getArea: function (polygon) {

                   var area = 0, len = polygon.rings[0].length, radius = 6371008.8;
                   var x1 = polygon.rings[0][len - 1][0];
                   var y1 = polygon.rings[0][len - 1][1];
                   for (var i = 0; i < len; i++) {
                         console.log(lonLatToMercator(new Point(polygon.rings[0][i][0], polygon.rings[0][i][1])));
                         var x2 = polygon.rings[0][i][0], y2 = polygon.rings[0][i][1];
                         area += toRadians(x2 - x1) * (2 + Math.sin(toRadians(y1)) + Math.sin(toRadians(y2)));
                         x1 = x2;
                         y1 = y2;
                   }
                    return area * radius * radius / 2.0;
             },

4.总结

以上就是我总结的计算距离和面积的三种方法。


  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值