Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将线条字符串转换为多边形_C#_Sql_Sql Server - Fatal编程技术网

C# 将线条字符串转换为多边形

C# 将线条字符串转换为多边形,c#,sql,sql-server,C#,Sql,Sql Server,如何使用MS SQL或C将封闭的linestring转换为polgyon for Geography。我正在尝试构建此数据,以便可以在MS SQL数据库中搜索数据。当我尝试使用函数stgeomefromwkb转换数据时,它没有返回正确的形状 DECLARE @data geography; SET @data= 'LINESTRING(145.13527778 13.64166667, 144.74694444 13.47666667, 144.63722222 13.51194444, 14

如何使用MS SQL或C将封闭的linestring转换为polgyon for Geography。我正在尝试构建此数据,以便可以在MS SQL数据库中搜索数据。当我尝试使用函数stgeomefromwkb转换数据时,它没有返回正确的形状

DECLARE @data geography;
 SET @data= 'LINESTRING(145.13527778 13.64166667, 144.74694444 13.47666667, 144.63722222 13.51194444, 144.61944444 13.5875, 144.62337227 13.60962359, 144.62777753 13.63154738, 144.63412072 13.65301205, 144.64235403 13.6738541, 144.65241522 13.69391474, 144.66422807 13.71304108, 144.67770294 13.73108731, 144.69273746 13.74791585, 144.70921729 13.76339835, 144.72701699 13.7774167,144.74600098 13.78986396,144.76602456 13.80064514,144.78693505 13.80967796,144.80857293 13.81689348,144.83077307 13.82223661,144.85336602 13.82566656,144.87617929 13.82715716,144.8990387 13.826697,144.92176971 13.82428962,144.94419878 13.81995338,144.96615467 13.8137214,144.98746983 13.80564125,145.0079816 13.79577461,145.02753354 13.78419678,145.0459766 13.77099612,145.06317023 13.75627335,145.07898353 13.74014079,145.09329617 13.7227215,145.10599934 13.70414829,145.1169966 13.68456278,145.12620454 13.66411424, 145.13355348 13.64295851, 145.13527778 13.64166667)'; 

 --This shape looks like this
结果是错误的,如下所示。

这是一个很难回答的问题,因为您将获得预期的结果,但问题是如何将线字符串转换为多边形。这个答案将使用替换,但肯定可以通过其他方式完成,例如您尝试的方法。此外,我们将添加一些不必要的代码来显示该方法。这基于以下假设:源值采用封闭的LINESTRING格式

请参见这组查询:

DECLARE @predata varchar(MAX) = 'LINESTRING(145.13527778 13.64166667, 144.74694444 13.47666667, 144.63722222 13.51194444, 144.61944444 13.5875, 144.62337227 13.60962359, 144.62777753 13.63154738, 144.63412072 13.65301205, 144.64235403 13.6738541, 144.65241522 13.69391474, 144.66422807 13.71304108, 144.67770294 13.73108731, 144.69273746 13.74791585, 144.70921729 13.76339835, 144.72701699 13.7774167,144.74600098 13.78986396,144.76602456 13.80064514,144.78693505 13.80967796,144.80857293 13.81689348,144.83077307 13.82223661,144.85336602 13.82566656,144.87617929 13.82715716,144.8990387 13.826697,144.92176971 13.82428962,144.94419878 13.81995338,144.96615467 13.8137214,144.98746983 13.80564125,145.0079816 13.79577461,145.02753354 13.78419678,145.0459766 13.77099612,145.06317023 13.75627335,145.07898353 13.74014079,145.09329617 13.7227215,145.10599934 13.70414829,145.1169966 13.68456278,145.12620454 13.66411424, 145.13355348 13.64295851, 145.13527778 13.64166667)';
DECLARE @data geography;
DECLARE @linestring geography = @predata;
DECLARE @srid int;
SET @predata = REPLACE(@predata, 'LINESTRING', 'POLYGON(') + ')';
SELECT @predata AS PolygonString
SET @data = geography::STGeomFromText(@predata, @linestring.STSrid);
SELECT @data AS GeographyPolygon
声明变量后,我对LINESTRING的string/varchar表示进行了一次简单的替换,将其转换为多边形

结果是:

PolygonString
POLYGON((145.13527778 13.64166667, 144.74694444 13.47666667, 144.63722222 13.51194444, 144.61944444 13.5875, 144.62337227 13.60962359, 144.62777753 13.63154738, 144.63412072 13.65301205, 144.64235403 13.6738541, 144.65241522 13.69391474, 144.66422807 13.71304108, 144.67770294 13.73108731, 144.69273746 13.74791585, 144.70921729 13.76339835, 144.72701699 13.7774167,144.74600098 13.78986396,144.76602456 13.80064514,144.78693505 13.80967796,144.80857293 13.81689348,144.83077307 13.82223661,144.85336602 13.82566656,144.87617929 13.82715716,144.8990387 13.826697,144.92176971 13.82428962,144.94419878 13.81995338,144.96615467 13.8137214,144.98746983 13.80564125,145.0079816 13.79577461,145.02753354 13.78419678,145.0459766 13.77099612,145.06317023 13.75627335,145.07898353 13.74014079,145.09329617 13.7227215,145.10599934 13.70414829,145.1169966 13.68456278,145.12620454 13.66411424, 145.13355348 13.64295851, 145.13527778 13.64166667))
在最后一个括号中有一个带+字符串连接的有效多边形字符串值后,我们可以将其传递给stgeomefromtext函数,如下所示:

SET @data =  geography::STGeomFromText(@predata, @linestring.STSrid);
最后,通过选择地理类型@数据变量,我们得到空间结果

SELECT @data AS GeographyPolygon
该多边形与您显示的多边形相同。该比例与LINESTRING值的比例非常不同,因为它位于SRID 4326的完整地理平面表示形式上。这类定义:

由于SRID 4326的投影边界为:

预计界限:-180.0000,-90.0000,180.0000,90.0000


这意味着与初始线串相比,结果的比例非常大。如果放大9°-18°乘以140°-160°的象限,您将看到多边形。

这是一个很难回答的问题,因为您将获得预期的结果,但问题是如何将线串转换为多边形。这个答案将使用替换,但肯定可以通过其他方式完成,例如您尝试的方法。此外,我们将添加一些不必要的代码来显示该方法。这基于以下假设:源值采用封闭的LINESTRING格式

请参见这组查询:

DECLARE @predata varchar(MAX) = 'LINESTRING(145.13527778 13.64166667, 144.74694444 13.47666667, 144.63722222 13.51194444, 144.61944444 13.5875, 144.62337227 13.60962359, 144.62777753 13.63154738, 144.63412072 13.65301205, 144.64235403 13.6738541, 144.65241522 13.69391474, 144.66422807 13.71304108, 144.67770294 13.73108731, 144.69273746 13.74791585, 144.70921729 13.76339835, 144.72701699 13.7774167,144.74600098 13.78986396,144.76602456 13.80064514,144.78693505 13.80967796,144.80857293 13.81689348,144.83077307 13.82223661,144.85336602 13.82566656,144.87617929 13.82715716,144.8990387 13.826697,144.92176971 13.82428962,144.94419878 13.81995338,144.96615467 13.8137214,144.98746983 13.80564125,145.0079816 13.79577461,145.02753354 13.78419678,145.0459766 13.77099612,145.06317023 13.75627335,145.07898353 13.74014079,145.09329617 13.7227215,145.10599934 13.70414829,145.1169966 13.68456278,145.12620454 13.66411424, 145.13355348 13.64295851, 145.13527778 13.64166667)';
DECLARE @data geography;
DECLARE @linestring geography = @predata;
DECLARE @srid int;
SET @predata = REPLACE(@predata, 'LINESTRING', 'POLYGON(') + ')';
SELECT @predata AS PolygonString
SET @data = geography::STGeomFromText(@predata, @linestring.STSrid);
SELECT @data AS GeographyPolygon
声明变量后,我对LINESTRING的string/varchar表示进行了一次简单的替换,将其转换为多边形

结果是:

PolygonString
POLYGON((145.13527778 13.64166667, 144.74694444 13.47666667, 144.63722222 13.51194444, 144.61944444 13.5875, 144.62337227 13.60962359, 144.62777753 13.63154738, 144.63412072 13.65301205, 144.64235403 13.6738541, 144.65241522 13.69391474, 144.66422807 13.71304108, 144.67770294 13.73108731, 144.69273746 13.74791585, 144.70921729 13.76339835, 144.72701699 13.7774167,144.74600098 13.78986396,144.76602456 13.80064514,144.78693505 13.80967796,144.80857293 13.81689348,144.83077307 13.82223661,144.85336602 13.82566656,144.87617929 13.82715716,144.8990387 13.826697,144.92176971 13.82428962,144.94419878 13.81995338,144.96615467 13.8137214,144.98746983 13.80564125,145.0079816 13.79577461,145.02753354 13.78419678,145.0459766 13.77099612,145.06317023 13.75627335,145.07898353 13.74014079,145.09329617 13.7227215,145.10599934 13.70414829,145.1169966 13.68456278,145.12620454 13.66411424, 145.13355348 13.64295851, 145.13527778 13.64166667))
在最后一个括号中有一个带+字符串连接的有效多边形字符串值后,我们可以将其传递给stgeomefromtext函数,如下所示:

SET @data =  geography::STGeomFromText(@predata, @linestring.STSrid);
最后,通过选择地理类型@数据变量,我们得到空间结果

SELECT @data AS GeographyPolygon
该多边形与您显示的多边形相同。该比例与LINESTRING值的比例非常不同,因为它位于SRID 4326的完整地理平面表示形式上。这类定义:

由于SRID 4326的投影边界为:

预计界限:-180.0000,-90.0000,180.0000,90.0000


这意味着与初始线串相比,结果的比例非常大。如果放大9°-18°乘以140°-160°的象限,将看到多边形。

如果将最后一行更改为

select @Polygon.ReorientObject();

我想你会找到想要的结果。您的线字符串存在所谓的环方向问题。指定点的顺序很重要。根据定义,多边形是减去目标多边形的整个球体。通过在多边形上调用ReorientObject,它……会重新确定对象的方向。

如果将最后一行更改为

select @Polygon.ReorientObject();

我想你会找到想要的结果。您的线字符串存在所谓的环方向问题。指定点的顺序很重要。根据定义,多边形是减去目标多边形的整个球体。通过在多边形上调用ReorientObject,它可以……重新确定对象的方向。

ReorientObject是问题的50%。只有当包络角小于90度时,我们才需要这样做

 /// <summary>
        /// Fixing ring orientation problem By calling ReorientObject() for all any shapes
        /// Shape must be reposition before insert into the database otherwise you have the wrong result especially with the polygon
        /// SQL Script example
        //        DECLARE @Polygon geography;
        //SET @Polygon = 'POLYGON((145.13527778 13.64166667, 144.74694444 13.47666667, 144.63722222 13.51194444, 144.61944444 13.5875, 144.62337227 13.60962359, 144.62777753 13.63154738, 144.63412072 13.65301205, 144.64235403 13.6738541, 144.65241522 13.69391474, 144.66422807 13.71304108, 144.67770294 13.73108731, 144.69273746 13.74791585, 144.70921729 13.76339835, 144.72701699 13.7774167,144.74600098 13.78986396,144.76602456 13.80064514,144.78693505 13.80967796,144.80857293 13.81689348,144.83077307 13.82223661,144.85336602 13.82566656,144.87617929 13.82715716,144.8990387 13.826697,144.92176971 13.82428962,144.94419878 13.81995338,144.96615467 13.8137214,144.98746983 13.80564125,145.0079816 13.79577461,145.02753354 13.78419678,145.0459766 13.77099612,145.06317023 13.75627335,145.07898353 13.74014079,145.09329617 13.7227215,145.10599934 13.70414829,145.1169966 13.68456278,145.12620454 13.66411424, 145.13355348 13.64295851, 145.13527778 13.64166667))'; 
        // --This shape looks like this, you have to zoom in to see, it is really small
        //select @Polygon, 'error here' as ErrorHere

        //set @Polygon=@Polygon.ReorientObject();
        //select @Polygon;

        //--Only convert if the EnvelopeAngle> 90
        //select 
        //case when @Polygon.EnvelopeAngle() > 90 then
        //@Polygon.ReorientObject()
        //  else
        //   @Polygon
        //end  

        //--Do not duplicate ReorientObject it will cost error like below
        //set @Polygon = @Polygon.ReorientObject();
        //        select @Polygon;

        /// </summary>
        /// <param name="dataPoints">Example POLYGON((145.13527778 13.64166667, 144.74694444 13.47666667, 144.63722222 13.51194444, 144.61944444 13.5875, 144.62337227 13.60962359, 144.62777753 13.63154738, 144.63412072 13.65301205, 144.64235403 13.6738541, 144.65241522 13.69391474, 144.66422807 13.71304108, 144.67770294 13.73108731, 144.69273746 13.74791585, 144.70921729 13.76339835, 144.72701699 13.7774167,144.74600098 13.78986396,144.76602456 13.80064514,144.78693505 13.80967796,144.80857293 13.81689348,144.83077307 13.82223661,144.85336602 13.82566656,144.87617929 13.82715716,144.8990387 13.826697,144.92176971 13.82428962,144.94419878 13.81995338,144.96615467 13.8137214,144.98746983 13.80564125,145.0079816 13.79577461,145.02753354 13.78419678,145.0459766 13.77099612,145.06317023 13.75627335,145.07898353 13.74014079,145.09329617 13.7227215,145.10599934 13.70414829,145.1169966 13.68456278,145.12620454 13.66411424, 145.13355348 13.64295851, 145.13527778 13.64166667))</param>
        /// <returns></returns>
        public static string ReorientObject(string dataPoints)
        {
            //Convert to DbGeography
            DbGeography newGeography = DbGeography.FromText(dataPoints.ToString(), 4326);

            //Fixing ring orientation problem By calling ReorientObject() on the polygon
            SqlGeography parseData = SqlGeography.Parse(dataPoints);
            if (parseData.EnvelopeAngle() > 90)
            {
                parseData= parseData.ReorientObject();
            }
            //Take the new reposition of the poing
            dataPoints = DbGeography.FromText(parseData.ToString(), 4326).AsText();
            return dataPoints;
        }

重定向对象是问题的50%。只有当包络角小于90度时,我们才需要这样做

 /// <summary>
        /// Fixing ring orientation problem By calling ReorientObject() for all any shapes
        /// Shape must be reposition before insert into the database otherwise you have the wrong result especially with the polygon
        /// SQL Script example
        //        DECLARE @Polygon geography;
        //SET @Polygon = 'POLYGON((145.13527778 13.64166667, 144.74694444 13.47666667, 144.63722222 13.51194444, 144.61944444 13.5875, 144.62337227 13.60962359, 144.62777753 13.63154738, 144.63412072 13.65301205, 144.64235403 13.6738541, 144.65241522 13.69391474, 144.66422807 13.71304108, 144.67770294 13.73108731, 144.69273746 13.74791585, 144.70921729 13.76339835, 144.72701699 13.7774167,144.74600098 13.78986396,144.76602456 13.80064514,144.78693505 13.80967796,144.80857293 13.81689348,144.83077307 13.82223661,144.85336602 13.82566656,144.87617929 13.82715716,144.8990387 13.826697,144.92176971 13.82428962,144.94419878 13.81995338,144.96615467 13.8137214,144.98746983 13.80564125,145.0079816 13.79577461,145.02753354 13.78419678,145.0459766 13.77099612,145.06317023 13.75627335,145.07898353 13.74014079,145.09329617 13.7227215,145.10599934 13.70414829,145.1169966 13.68456278,145.12620454 13.66411424, 145.13355348 13.64295851, 145.13527778 13.64166667))'; 
        // --This shape looks like this, you have to zoom in to see, it is really small
        //select @Polygon, 'error here' as ErrorHere

        //set @Polygon=@Polygon.ReorientObject();
        //select @Polygon;

        //--Only convert if the EnvelopeAngle> 90
        //select 
        //case when @Polygon.EnvelopeAngle() > 90 then
        //@Polygon.ReorientObject()
        //  else
        //   @Polygon
        //end  

        //--Do not duplicate ReorientObject it will cost error like below
        //set @Polygon = @Polygon.ReorientObject();
        //        select @Polygon;

        /// </summary>
        /// <param name="dataPoints">Example POLYGON((145.13527778 13.64166667, 144.74694444 13.47666667, 144.63722222 13.51194444, 144.61944444 13.5875, 144.62337227 13.60962359, 144.62777753 13.63154738, 144.63412072 13.65301205, 144.64235403 13.6738541, 144.65241522 13.69391474, 144.66422807 13.71304108, 144.67770294 13.73108731, 144.69273746 13.74791585, 144.70921729 13.76339835, 144.72701699 13.7774167,144.74600098 13.78986396,144.76602456 13.80064514,144.78693505 13.80967796,144.80857293 13.81689348,144.83077307 13.82223661,144.85336602 13.82566656,144.87617929 13.82715716,144.8990387 13.826697,144.92176971 13.82428962,144.94419878 13.81995338,144.96615467 13.8137214,144.98746983 13.80564125,145.0079816 13.79577461,145.02753354 13.78419678,145.0459766 13.77099612,145.06317023 13.75627335,145.07898353 13.74014079,145.09329617 13.7227215,145.10599934 13.70414829,145.1169966 13.68456278,145.12620454 13.66411424, 145.13355348 13.64295851, 145.13527778 13.64166667))</param>
        /// <returns></returns>
        public static string ReorientObject(string dataPoints)
        {
            //Convert to DbGeography
            DbGeography newGeography = DbGeography.FromText(dataPoints.ToString(), 4326);

            //Fixing ring orientation problem By calling ReorientObject() on the polygon
            SqlGeography parseData = SqlGeography.Parse(dataPoints);
            if (parseData.EnvelopeAngle() > 90)
            {
                parseData= parseData.ReorientObject();
            }
            //Take the new reposition of the poing
            dataPoints = DbGeography.FromText(parseData.ToString(), 4326).AsText();
            return dataPoints;
        }

你的多边形在那里,但是比例太小了。如果你放大9度乘140度的象限,你可以看到它。它很小。至于如何转换为多边形。我相信您可以将线字符串值包装在多边形中,它将返回结果。试试看。像这个集合@data=geography::stgeomefromtext'POLYGON…',4326;我无法将整个字符串粘贴到注释中,因为它太长了,但请将您的值放在椭圆中,您就会看到。您的多边形在那里,但比例太小了。如果你放大9度乘140度的象限,你可以看到它。它很小。至于如何转换为多边形。我相信您可以将线字符串值包装在多边形中,它将返回结果。试试看。像这个集合@data=geography::stgeomefromtext'POLYGON…',4326;我无法将整个字符串粘贴到注释中,因为它太长了,但请将您的值放在省略号和
你会明白的。非常感谢我所需要的重定向对象,我真不敢相信MS SQL自己不会这么做。现在我必须在插入数据库之前重新生成数据。多亏了我所需要的重定向对象,我真不敢相信MS SQL自己不会这么做。现在我必须在插入数据库之前重新生成数据。