我正在尝试使用Bing Maps在我的系统中重新创建税图。我的问题在于列出我正在创建的多边形边长的英尺。我很清楚如何从我的数据库中的MSSQL 2012几何或地理项目中获取我创建的折线的长度。我无法弄清楚如何有效地向用户呈现它。我对如何做到这一点有两个想法。
两个选项中的任何一个都可以作为可接受的解决方案。我使用本教程创建了当前的环境,因此我希望以某种方式将解决方案集成到其中: How to create a spatial web service that connects a database to Bing Maps using EF5 请注意,我的实现仅使用代码的国家/地区部分,因此我不需要处理单个点,例如该教程中的城市。
可以在此处找到处理我需要编辑的地图上的绘图的相关代码: Bing Maps v7 WellKnowTextModule
答案 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创建自定义推送:
答案 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);
}
}