9
votes

Reformat Sqlgeography Polygons à Json

Je construis un service Web qui sert des données de limites géographiques au format JSON.

Les données géographiques sont stockées dans une base de données SQL Server 2008 R2 à l'aide du type de géographie dans une table. J'utilise [colleName] .tostring () code> méthode pour renvoyer les données de polygone sous forme de texte. P>

exemple de sortie: p>

Regex latlngMatch = new Regex(@"(-?[0-9]{1}\.\d*)\s(\d{2}.\d*)(?:\s0\s0,?)?", RegexOptions.Compiled);

    private string ConvertPolysToJson(string polysIn)
    {
        return this.latlngMatch.Replace(polysIn.Remove(0, polysIn.IndexOf("(")) // remove POLYGON or MULTIPOLYGON
                                               .Replace("(", "[")  // convert to JSON array syntax
                                               .Replace(")", "]"), // same as above
                                               "{lng:$1,lat:$2},"); // reformat lat/lng pairs to JSON objects
    }


2 commentaires

Remarque: les définitions géographiques sont uniquement pour GB, qui se reflète dans la regex.


Ne retournez pas les données comme texte. Retournez-le directement en utilisant sqlgeométrie ou dbgeométrie . Ou le retour est comme Geojson directement de la DB.


6 Réponses :


1
votes

Les chaînes sont immuables dans .NET, alors lorsque vous remplacez certains, vous créez une copie éditée de la chaîne précédente. Ce n'est pas si critique pour la performance, comme pour l'utilisation de la mémoire.

regarder json.net P >

ou utilisez StringBuilder pour le générer correctement. P>

StringBuilder sb = new StringBuilder();
sb.AppendFormat();


1 commentaires

Je sais cela, et j'utilise déjà json.net. Parce que les chaînes n'ont pas de délimiteur, je ne peux pas les cracher, puis les ajouter à StringBuilder ou à un objet JSON. Je peux détecter les paires lat / longs, mais la bracketing dans la piqûre est également importante car elle indique la profondeur de la matrice, sinon je pouvais simplement prendre mes matchs et construire un objet JSON et ne pas vous soucier des crochets. Ces chaînes sont essentiellement des objets JSON de toute façon, ils doivent simplement être reformatés vers la syntaxe JSON.



13
votes

Encore une fois juste pour le fermer, je répondrai à ma propre question avec la solution im en utilisant.

Cette méthode prend la sortie à partir d'un Tostring () code> Appel sur un MS SQL Type de géographie Code>. Si la chaîne renvoyée contient des données de polygone contient des points GPS de formulaire, cette méthode analysera et la reformaté à une piqûre JSON. P>

public static class PolyConverter
{
    static Regex latlngMatch = new Regex(@"(-?\d{1,2}\.\dE-\d+|-?\d{1,2}\.?\d*)\s(-?\d{1,2}\.\dE-\d+|-?\d{1,2}\.?\d*)\s?0?\s?0?,?", RegexOptions.Compiled);
    static Regex reformat = new Regex(@"\[,", RegexOptions.Compiled);

    public static string ConvertPolysToJson(string polysIn)
    {
        var formatted = reformat.Replace(
                        latlngMatch.Replace(
                        polysIn.Remove(0, polysIn.IndexOf("(")), ",{lng:$1,lat:$2}")
                        .Replace("(", "[")
                        .Replace(")", "]"), "[");

        if (polysIn.Contains("MULTIPOLYGON"))
        {
            formatted = formatted.Replace("[[", "[")
                                 .Replace("]]", "]")
                                 .Replace("[[[", "[[")
                                 .Replace("]]]", "]]");
        }

        return formatted;
    }
}


0 commentaires

10
votes

Pour répondre à votre question sur l'efficacité, pour ce cas particulier, je ne pense pas que Remplacer strong> vs RegEx strong> va être grande que d'une différence. Tout ce que nous changeons vraiment est une parenthèse et des virgules. Personnellement, je préfère faire les choses dans TSQL pour les applications Web parce que je peux décharger le travail de calcul sur le SQL Server au lieu du serveur Web. Dans mon cas, j'ai beaucoup de données que je générer une carte et donc ne veux pas enliser le serveur Web avec beaucoup de conversions de données. De plus, pour la performance, je l'habitude de mettre plus de puissance sur le serveur SQL que je fais un serveur web, même s'il y a une différence entre les deux fonctions, si Remplacer strong> est moins efficace, il est au moins en cours de traitement par un serveur avec beaucoup plus de ressources. En général, je veux que mon serveur web la gestion des connexions aux clients et mes calculs de traitement des données SQL Server. Cela permet aussi mes scripts de serveur Web propre et efficace. Donc, ma suggestion est comme suit:

Ecrire une fonction TSQL Scalar dans votre base de données. Celui-ci utilise SQL Fonction REPLACE strong> et est un peu la force brute, mais il joue vraiment bien. Cette fonction peut être utilisée directement sur une instruction SELECT ou pour créer des colonnes calculées dans une table si vous voulez vraiment simplifier votre code de serveur Web. À l'heure actuelle cet exemple ne supporte que POINT, POLYGONE et MULTIPOLYGON et fournit l'élément JSON "géométrie" pour le format GeoJSON. P>

GetGeoJSON Scalar Fonction strong> p>

SELECT dbo.GetGeoJSON([COLUMN]) as Geometry From [TABLE]


2 commentaires

Je reçois cette géométrie d'erreur est incompatible avec la géographie


Où avez-vous obtenu cette erreur? Lorsque vous appelez la fonction? Si tel est le cas, il faut la géographie comme argument, pas la géométrie.



12
votes

Pour convertir de WKT en Geojson, vous pouvez utiliser NetTopologysuite à partir de Nuget. Ajouter NetTopologysuite et NETTOPOLOGYSUITE.IO.GEOJSON

{
  "features": [
    {
      "type": "Feature",
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              10.0,
              20.0
            ],
            [
              30.0,
              40.0
            ],
            [
              50.0,
              60.0
            ],
            [
              10.0,
              20.0
            ]
          ]
        ]
      },
      "properties": {}
    }
  ],
  "type": "FeatureCollection"
}


2 commentaires

Jeepers, c'est génial. Merci! Cela devrait être top.


Probablement la meilleure réponse ces jours-ci, car j'ai répondu à l'origine ma propre question il y a plus de 10 ans!



2
votes

La méthode décrite dans la réponse de James fonctionne bien. Mais j'ai récemment trouvé une erreur lors de la conversion de WKT où la longitude avait une valeur supérieure à 99.

J'ai changé l'expression régulière: xxx

remarque le deuxième "2" a été changé en une "3" pour permettre à la longitude d'aller jusqu'à 180.


0 commentaires

1
votes

fonction utilitaire utilisée pour formater des cellules spatiales comme Geojson est présentée ci-dessous. XXX


0 commentaires