简体   繁体   English

空间数据类型(几何)到 GeoJSON

[英]Spatial Datatype (geometry) to GeoJSON

I want to convert geom ( geometry ) datatype to GeoJSON.我想将geom ( geometry ) 数据类型转换为 GeoJSON。 How could I do that?我怎么能那样做?

For example, the geometry in WKT:例如,WKT 中的几何图形:

    POLYGON((455216.346127297 4288433.28426224,455203.386722146 4288427.76317716,455207.791765017 4288417.51116228,455220.784166744 4288423.30230044,455216.346127297 4288433.28426224))

To the following GeoJSON:到以下 GeoJSON:

{ "type": "Polygon",
    "coordinates": [
      [ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ],
      [ [100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2] ]
    ]
}

I had this same need.我也有同样的需求。 We have a large database containing tables with GEOMETRY columns in SQL Server.我们有一个大型数据库,其中包含 SQL Server 中带有 GEOMETRY 列的表。 I felt that it would be more desirable to be able to get a single string object as a result from a stored proceedure that would contain the GeoJson.我觉得能够从包含 GeoJson 的存储过程中获取单个字符串对象是更可取的。 I wrote a function that takes a geometry instance as an object and returns a GeoJson string.我编写了一个函数,它将几何实例作为对象并返回一个 GeoJson 字符串。

CREATE FUNCTION [dbo].[geomToGeoJSON] (@geom GEOMETRY)
RETURNS VARCHAR(MAX)
AS
BEGIN
-- Declare the return variable here
    DECLARE @geoJSON VARCHAR(MAX)


    DECLARE @Ngeom GEOMETRY
    DECLARE @ptCounter INT
    DECLARE @numPt INT
    DECLARE @ringCounter INT
    DECLARE @numRing INT
    DECLARE @gCounter INT
    DECLARE @numGeom INT
    DECLARE @handled BIT = 0
    DECLARE @extRing GEOMETRY
    DECLARE @intRing GEOMETRY

    -- fix bad geometries and enforce ring orientation
    SET @geom = @geom.STUnion(@geom.STPointN(1)).MakeValid()

    -- Point ----------------------------
    IF (@geom.STGeometryType() = 'Point')
    BEGIN
        SET @geoJSON = '{ "type": "Point", "coordinates": [' + LTRIM(RTRIM(STR(@geom.STX, 38, 8))) + ', ' + LTRIM(RTRIM(STR(@geom.STY, 38, 8))) + '] }'
        SET @handled = 1
    END


    -- MultiPoint ---------------------------------------------
    IF (
        @handled = 0
        AND @geom.STGeometryType() = 'MultiPoint'
        )
    BEGIN
        SET @gCounter = 1
        SET @numGeom = @geom.STNumGeometries()

        SET @geoJSON = '{ "type": "MultiPoint", "coordinates": ['

        WHILE @gCounter <= @numGeom
        BEGIN
            SET @geoJSON += '[' + LTRIM(RTRIM(STR(@geom.STGeometryN(@gCounter).STX, 38, 8))) + ', ' + LTRIM(RTRIM(STR(@geom.STGeometryN(@gCounter).STY, 38, 8))) + '], '
            SET @gCounter += 1
        END

        SET @geoJSON = LEFT(@geoJSON, LEN(@geoJSON) - 1) + '] }'
        SET @handled = 1
    END




    -- LineString ---------------------------------------------
    IF (
        @handled = 0
        AND @geom.STGeometryType() = 'LineString'
        )
    BEGIN
        SET @ptCounter = 1
        SET @numPt = @geom.STNumPoints()

        SET @geoJSON = '{ "type": "LineString", "coordinates": ['

        WHILE @ptCounter <= @numPt
        BEGIN
            SET @geoJSON += '[' + LTRIM(RTRIM(STR(@geom.STPointN(@ptCounter).STX, 38, 8))) + ', ' + LTRIM(RTRIM(STR(@geom.STPointN(@ptCounter).STY, 38, 8))) + '], '
            SET @ptCounter += 1
        END

        SET @geoJSON = LEFT(@geoJSON, LEN(@geoJSON) - 1) + ' ] }'
        SET @handled = 1
    END




    -- MultiLineString ---------------------------------------------
    IF (
        @handled = 0
        AND @geom.STGeometryType() = 'MultiLineString'
        )
    BEGIN
        SET @gCounter = 1
        SET @numGeom = @geom.STNumGeometries()

        SET @geoJSON = '{ "type": "MultiLineString", "coordinates": ['

        WHILE @gCounter <= @numGeom
        BEGIN
            SET @Ngeom = @geom.STGeometryN(@gCounter)
            SET @geoJSON += '['
            SELECT
                @ptCounter = 1
                ,@numPt = @Ngeom.STNumPoints()

            WHILE @ptCounter <= @numPt
            BEGIN
                SET @geoJSON += '[' + LTRIM(RTRIM(STR(@Ngeom.STPointN(@ptCounter).STX, 38, 8))) + ', ' + LTRIM(RTRIM(STR(@Ngeom.STPointN(@ptCounter).STY, 38, 8))) + '], '
                SET @ptCounter += 1
            END

            SET @geoJSON = LEFT(@geoJSON, LEN(@geoJSON) - 1) + '],'

            SET @gCounter += 1
        END

        SET @geoJSON = LEFT(@geoJSON, LEN(@geoJSON) - 1) + '] }'
        SET @handled = 1
    END




    -- Polygon ---------------------------------------------
    IF (
        @handled = 0
        AND @geom.STGeometryType() = 'Polygon'
        )
    BEGIN
        SET @extRing = @geom.STExteriorRing()

        SET @geoJSON = '{ "type": "Polygon", "coordinates": [['

        SELECT
            @ptCounter = 1
            ,@numPt = @extRing.STNumPoints()

        WHILE @ptCounter <= @numPt
        BEGIN
            SET @geoJSON += '[' + LTRIM(RTRIM(STR(@extRing.STPointN(@ptCounter).STX, 38, 8))) + ', ' + LTRIM(RTRIM(STR(@extRing.STPointN(@ptCounter).STY, 38, 8))) + '], '
            SET @ptCounter += 1
        END

        SET @geoJSON = LEFT(@geoJSON, LEN(@geoJSON) - 1) + ']'

        SET @ringCounter = 1
        SET @numRing = @geom.STNumInteriorRing()

        WHILE @ringCounter <= @numRing
        BEGIN
            SET @geoJSON += ',['

            SET @intRing = @geom.STInteriorRingN(@ringCounter)
            -- set the ring orientation so that they are consistent
            SET @intRing = @intRing.STUnion(@intRing.STPointN(1)).MakeValid()

            SELECT
                @ptCounter = @intRing.STNumPoints()

            WHILE @ptCounter > 0
            BEGIN
                SET @geoJSON += '[' + LTRIM(RTRIM(STR(@intRing.STPointN(@ptCounter).STX, 38, 8))) + ', ' + LTRIM(RTRIM(STR(@intRing.STPointN(@ptCounter).STY, 38, 8))) + '], '
                SET @ptCounter -= 1
            END

            SET @geoJSON = LEFT(@geoJSON, LEN(@geoJSON) - 1) + ']'

            SET @ringCounter += 1
        END

        SET @geoJSON = LEFT(@geoJSON, LEN(@geoJSON) - 1) + ']] }'
        SET @handled = 1
    END




    -- MultiPolygon ---------------------------------------------
    IF (
        @handled = 0
        AND @geom.STGeometryType() = 'MultiPolygon'
        )
    BEGIN
        SELECT
            @gCounter = 1
            ,@numGeom = @geom.STNumGeometries()

        SET @geoJSON = '{ "type": "MultiPolygon", "coordinates": ['

        WHILE @gCounter <= @numGeom
        BEGIN
            SET @Ngeom = @geom.STGeometryN(@gCounter)

            SET @extRing = @Ngeom.STExteriorRing()

            SET @geoJSON += '[['

            SELECT
                @ptCounter = 1
                ,@numPt = @extRing.STNumPoints()

            -- add the exterior ring points to the json
            WHILE @ptCounter <= @numPt
            BEGIN
                SET @geoJSON += '[' + LTRIM(RTRIM(STR(@extRing.STPointN(@ptCounter).STX, 38, 8))) + ', ' + LTRIM(RTRIM(STR(@extRing.STPointN(@ptCounter).STY, 38, 8))) + '], '
                SET @ptCounter += 1
            END

            SET @geoJSON = LEFT(@geoJSON, LEN(@geoJSON) - 1) + ']'

            SET @ringCounter = 1
            SET @numRing = @Ngeom.STNumInteriorRing()

            -- add any internal ring points to the json
            WHILE @ringCounter <= @numRing
            BEGIN
                SET @geoJSON += ',['

                SET @intRing = @Ngeom.STInteriorRingN(@ringCounter)
                -- make sure the ring orientation is the same every time
                SET @intRing = @intRing.STUnion(@intRing.STPointN(1)).MakeValid()

                SELECT
                    @ptCounter = @intRing.STNumPoints()

                WHILE @ptCounter > 0
                BEGIN
                    SET @geoJSON += '[' + LTRIM(RTRIM(STR(@intRing.STPointN(@ptCounter).STX, 38, 8))) + ', ' + LTRIM(RTRIM(STR(@intRing.STPointN(@ptCounter).STY, 38, 8))) + '], '
                    SET @ptCounter -= 1
                END

                SET @geoJSON = LEFT(@geoJSON, LEN(@geoJSON) - 1) + ']'

                SET @ringCounter += 1
            END



            SET @geoJSON += '],'
            SET @gCounter += 1
        END

        SET @geoJSON = LEFT(@geoJSON, LEN(@geoJSON) - 1) + '] }'
        SET @handled = 1
    END






    IF (@handled = 0)
    BEGIN
        SET @geoJSON = '{"type": "' + @geom.STGeometryType() + '", "coordinates": []}'
    END




    RETURN @geoJSON



END

Then I can either just select an individual GeoJSON object like this:然后我可以像这样选择一个单独的 GeoJSON 对象:

    SELECT dbo.geomToGeoJSON(GEOMCOLNAME) FROM DB.gis.PARCEL WHERE PARCEL = 'R1525750900'

and get a result that looks like并得到一个看起来像的结果

    {
        "type": "Polygon",
        "coordinates": [
            [
                [-116.27593761, 43.62939598],
                [-116.27558219, 43.62939633],
                [-116.27558253, 43.62955520],
                [-116.27582493, 43.62955445],
                [-116.27582534, 43.62963010],
                [-116.27593893, 43.62962975],
                [-116.27593761, 43.62939598]
            ]
        ]
    }

Or I can package an entire set of objects into a FeatureCollection like this:或者我可以像这样将一整套对象打包到一个 FeatureCollection 中:

        DECLARE @GeoJSON VARCHAR(MAX)
        SET @GeoJSON = '{"type": "FeatureCollection", "features": ['

        SELECT
            @GeoJSON += '{"type": "Feature", "geometry": ' + sde_apps.dbo.geomToGeoJSON(SHAPE) + ', "properties": { "Parcel": "' + PARCEL + '"}},'
        FROM
            db.gis.PARCEL
        WHERE
            SUBNM LIKE @subnm


        SET @GeoJSON = LEFT(@GeoJSON, LEN(@GeoJSON) - 1) + ']}'

        SELECT
            @GeoJSON

Query performance depends on the complexity and number of geometries, but I typically get a result in ~2 tenths of a second.查询性能取决于几何的复杂性和数量,但我通常在大约十分之二秒内得到结果。

I have validated by using example geometries from MSDN and then entering the resulting GeoJSON into http://geojsonlint.com/ .我已经使用 MSDN 中的示例几何图形进行了验证,然后将生成的 GeoJSON 输入到http://geojsonlint.com/ 中 I know this is a year old but I still have a need and I suspect anyone without a mapserver could generate their own simple mapserver using something like this to draw layers on Bing Maps, etc.我知道这已经一年了,但我仍然有需求,我怀疑没有地图服务器的任何人都可以使用类似的东西在 Bing 地图等上绘制图层来生成自己的简单地图服务器。

I think, you can produce geojson at server side when you get data from Sql Server.我认为,当您从 Sql Server 获取数据时,您可以在服务器端生成 geojson。

You should examine GeoJSON.Net and similar question你应该检查GeoJSON.Net类似的问题

var modelF = new List<GeoJSON.Net.Feature.Feature>();
foreach (DataRow dr in ds.Tables[0].Rows)
     {
       var point = new GeoJSON.Net.Geometry.Point(new GeoJSON.Net.Geometry.GeographicPosition(Convert.ToDouble(dr["latitude"].ToString()), Convert.ToDouble(dr["longitude"].ToString())));
       var featureProperties = new Dictionary<string, object> { };
       foreach (DataColumn dataColumn in ds.Tables[0].Columns)
            {
              featureProperties.Add(dataColumn.ColumnName, dr[dataColumn].ToString());
            }
       modelF.Add(new GeoJSON.Net.Feature.Feature(point, featureProperties));
     }
var fcol = new FeatureCollection(modelF);
var serializedData = JsonConvert.SerializeObject(fcol, Formatting.Indented, new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver(), NullValueHandling = NullValueHandling.Ignore });
return serializedData;

have a goo day.有一个美好的一天。

If you have access to PostgreSQL/PostGIS, you can use ST_GeomFromText to read in the geometry and ST_AsGeoJSON to save the geometry as a GeoJSON:如果你有机会到PostgreSQL / PostGIS的,你可以使用ST_GeomFromText在几何和阅读ST_AsGeoJSON保存几何图形作为GeoJSON的:

SELECT ST_AsGeoJSON(ST_GeomFromText('POLYGON((455216.346127297 
 4288433.28426224,455203.386722146 4288427.76317716,455207.791765017
 4288417.51116228,455220.784166744 4288423.30230044,455216.346127297
 4288433.28426224))'));

, which generates: , 产生:

-------------------------------------------------------------------------------

 {"type":"Polygon","coordinates":[[[455216.346127297,4288433.28426224],
[455203.386722146,4288427.76317716],[455207.791765017,4288417.51116228],
[455220.784166744,4288423.30230044],[455216.346127297,4288433.28426224]]]}

    (1 row)

That works for me (SQL Server)这对我有用(SQL Server)

  CREATE FUNCTION dbo.GEO_to_json( @geo GEOGRAPHY)
RETURNS nvarchar(MAX) AS
BEGIN
RETURN  
(SELECT
'{' +
(CASE @geo.STGeometryType()
WHEN 'POINT' THEN
'"type": "Point","coordinates":' +
REPLACE(REPLACE(REPLACE(REPLACE(@geo.ToString(),'POINT ',''),'(','['),')',']'),' ',',')
WHEN 'POLYGON' THEN
'"type": "Polygon","coordinates":' +
'[' + REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@geo.ToString(),'POLYGON ',''),'(','['),')',']'),'], ',']],['),', ','],['),' ',',') + ']'
WHEN 'MULTIPOLYGON' THEN
'"type": "MultiPolygon","coordinates":' +
'[' + REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@geo.ToString(),'MULTIPOLYGON ',''),'(','['),')',']'),'], ',']],['),', ','],['),' ',',') + ']'
WHEN 'MULTILINESTRING' THEN
'"type": "MultiLineString","coordinates":' +
'[' + REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@geo.ToString(),'MULTILINESTRING ',''),'(','['),')',']'),'], ',']],['),', ','],['),' ',',') + ']'
WHEN 'MULTIPOINT' THEN
'"type": "MultiPoint","coordinates":' +
REPLACE( REPLACE(REPLACE(REPLACE(REPLACE(@geo.ToString(),'MULTIPOINT ',''),'(','['),')',']'),' ',','),',,',', ')
WHEN 'LINESTRING' THEN
'"type": "LineString","coordinates":' +
'[' + REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@geo.ToString(),'LINESTRING ',''),'(','['),')',']'),'], ',']],['),', ','],['),' ',',') + ']'
ELSE NULL
END)
+'}')
END
GO

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用 SQL 空间将线串(geojson)转换为地理/几何 - Covnerting Linestring (geojson) to geography/geometry using SQL spatial 几何数据类型上的 UnionAggregate 以融合几何 - UnionAggregate on geometry datatype to fuse geometry STIntersect地理,几何数据类型 - STIntersect geography,geometry datatype 将 mssql 空间字段导入 geopandas/shapely geometry - Import mssql spatial fields into geopandas/shapely geometry SQL Server空间:变量是几何类型还是地理类型? - SQL Server Spatial: Is variable of type geometry or geography? Sql Server空间数据类型几何,STDistance和单位:获取米? - Sql Server spatial data type Geometry, STDistance and units : Get meters? EF Core:如何通过解析空间数据创建几何 - EF Core : How can I Create Geometry by Parsing Spatial Data 如何在空间 sql 查询中检查表 1 中的点几何是否存在于表 2 中的线几何 - How to check if point geometry from table 1 exist to line geometry from table 2 in spatial sql query 如何使用点几何列到 SQL 服务器空间中最近的线串几何列计算以“km”为单位的距离 - How to calculate distance in “km” using a points geometry column to the nearest linestring geometry column in SQL Server spatial R将具有几何数据类型的SQL Server查询转换为spatialpolygonsdataframe - R Converting SQL Server Query with Geometry Datatype to spatialpolygonsdataframe
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM