如何将折线长度添加到Bing地图多边形

时间:2014-08-06 20:32:17

标签: bing-maps polyline

我正在尝试使用Bing Maps在我的系统中重新创建税图。我的问题在于列出我正在创建的多边形边长的英尺。我很清楚如何从我的数据库中的MSSQL 2012几何或地理项目中获取我创建的折线的长度。我无法弄清楚如何有效地向用户呈现它。我对如何做到这一点有两个想法。

  1. 将长度直接放在相关折线上或附近。
  2. 在完整多边形上创建一个强调点,并在地图一侧列出,多边形边长基于顺时针顺序。
  3. 两个选项中的任何一个都可以作为可接受的解决方案。我使用本教程创建了当前的环境,因此我希望以某种方式将解决方案集成到其中: How to create a spatial web service that connects a database to Bing Maps using EF5 请注意,我的实现仅使用代码的国家/地区部分,因此我不需要处理单个点,例如该教程中的城市。

    可以在此处找到处理我需要编辑的地图上的绘图的相关代码: Bing Maps v7 WellKnowTextModule

2 个答案:

答案 0 :(得分:1)

如果你想在SQL2012中获取多边形的边界,你可以抓住它的外环。外环将是一个LineString,即" @ g.STExteriorRing()"。然后测量沿该线的长度。即" @ g.STExteriorRing()。STLength()"。但是,国家通常不仅仅是单个多边形,它们可以是MultiPpolygons或GeometryCollections。因此,要计算这些长度,我们必须做更多的工作。这是一个帮助方法,您可以添加到服务中以计算这些形状的周长:

private double CalculateLength(SqlGeometry geom)
{
    double length = 0;

    if(string.Compare(geom.STGeometryType().Value, "polygon", true) == 0)
    {

    }
    else if (string.Compare(geom.STGeometryType().Value, "multipolygon", true) == 0)
    {
        int numPolygon = geom.STNumGeometries().Value;
        for(int i = 1; i <= numPolygon; i++){
            length += geom.STGeometryN(i).STExteriorRing().STLength().Value;
        }                
    }
    else if (string.Compare(geom.STGeometryType().Value, "geometrycollection", true) == 0)
    {
        int numGeom = geom.STNumGeometries().Value;
        for (int i = 1; i <= numGeom; i++)
        {
            length += CalculateLength(geom.STGeometryN(i));
        }
    }

    return length;
}

要获取从服务器端到客户端的长度信息,请将属性添加到Country或BaseEntity类,如下所示:

[DataMember]
public double Perimeter { get; set; }

从这里开始,你可以在使用linq查询获取响应结果后使用一个调用前面的helper方法的简单循环来填充这个值:

for (int i = 0; i < r.Results.Count;i++)
{
    var geom = SqlGeometry.STGeomFromText(new System.Data.SqlTypes.SqlChars(r.Results[i].WKT), 4326);
    r.Results[i].Perimeter = CalculateLength(geom);
}

至于在地图上显示信息。将信息放置在折线上的一种简单方法是选择沿线的坐标,也许是中间的坐标,只需获取线中的#或坐标,找到中间索引并将该坐标用于图钉。然后,您可以使用带有文本的背景图像或使用自定义HTML创建自定义推送:

http://www.bingmapsportal.com/ISDK/AjaxV7#Pushpins4

http://www.bingmapsportal.com/ISDK/AjaxV7#Pushpins15

答案 1 :(得分:0)

希望在我接受的答案中添加一个附录,因为我觉得它有点改变了。

在研究这个问题时,我发现我实际上无法通过实体框架获得每个线段的长度。这是因为查询需要将我返回的地理位置更改为几何体,然后将其解析为基线线段,然后将这些线段更改回地理位置。即使在SQL中,查询也需要几分钟,因此不能在EF中动态运行。

我最终在我的数据库中创建了另一个表,其中包含我所拥有的每个多边形的每一侧的已解析的线段。然后我可以使用线段的质心作为人造城市。然后我将此逻辑添加到方法中for循环之后的问题中提到的教程中的DisplayData javascript函数中。

if (shape.getLength) {
  } else {
    var chkPolygon = data.Results[0].WKT.substring(0, data.Results[0].WKT.indexOf('(', 0));
    chkPolygon = chkPolygon.replace(/\s/g, '');

    switch (chkPolygon.toLowerCase()) {
      case 'point':

      case 'polygon':
        var latlonCheck = map.getCenter();
        var setSides = window.location.origin + "/SpatialService.svc/FindNearBy?latitude=" +
          latlonCheck.latitude + "&longitude=" + latlonCheck.longitude +
          "&radius=" + data.Results[0].ID + "&layerName=" + "city" + "&callback=?";

        CallRESTService(setSides, DisplaySides);
      default:
        break;
    }
  }

data.Results [0] .ID会在新表中找到该特定国家/地区的所有线段。然后DisplaySides函数用于将html图钉覆盖为&#34; cities&#34;在地图上每一面的适当点

function DisplaySides(getSides) {
  infobox.setOptions({ visible: false });
  if (getSides && getSides.Results != null) {
    for (var i = 0; i < getSides.Results.length; i++) {
      var sideLenFtShort = Math.round(getSides.Results[i].LengthFeet * 100) / 100;
      var htmlLenString = "<div style='font-size:14px;border:thin solid black;background-color:white;font-weight:bold;color:black;'>" + sideLenFtShort.toString(); + "</div>";
      var testString = {
        pushpinOptions: { width: null, height: null, htmlContent: htmlLenString }
      };
      var sideCtr = WKTModule.Read(getSides.Results[i].WKT, testString);

      dataLayer.push(sideCtr);
    }
  }
  else if (getSides && getSides.Error != null) {
    alert("Error: " + getSides.Error);
  }
}