Записки программиста, обо всем и ни о чем. Но, наверное, больше профессионального.

2013-05-21

GeoJSON 2 EsriJSON

По ходу реализации Mapfeatureserver встречаются занятные проблемы. В частности, результаты надо выдавать в JSON, а именно гео-JSON версии Esri. Из PostGIS я забираю честный GeoJSON а клиенту отдаю EsriJSON, который, по непонятным причинам отличается от GeoJSON чисто косметически. Для точек и полилиний преобразование тривиальное, а вот с полигонами пришлось повозиться.
    if geometryType == u'esriGeometryPoint':
        geometry = {"x": shape['coordinates'][0], "y": shape['coordinates'][1]}
    elif geometryType == u'esriGeometryPolyline':
        geometry = {"paths": shape['coordinates']}
    elif geometryType == u'esriGeometryPolygon':
        if len(shape['coordinates']) == 1:
            geometry = {"rings": shape['coordinates'][0]}
        else:
            geometry = {"rings": shape['coordinates']}
            rings = []
            for ring in shape['coordinates']:
                for e in ring:
                    rings.append(e)
            geometry = {"rings": rings}
    else:
        raise ValueError("geoJson2agJson: unknown geometry type '%s'" % geometryType)
Причем основная возня была на этапе проверок. Заодно выяснилось, что при копировании данных по схеме Esri FileGDB → shp → PostGIS полигоны оказываются перекрученными. В смысле первая, она же последняя точка оказывается в другом месте полигона, да и направление обхода точек может поменяться.

Пример данных для полигонов

GeoJSON выдает что-то типа
{u'type': u'MultiPolygon',
    u'coordinates': [
[[
    [4279602.386113361, 7520773.048816763],
    [4279572.070031156, 7520668.786903687],
    [4279455.184565822, 7520710.387695587],
    [4279602.386113361, 7520773.048816763]
]], [[
    [4208589.216875655, 7569584.6493480615],
    [4208579.177972653, 7569396.323268423],
    [4207803.281121826, 7568963.732610181],
    [4208589.216875655, 7569584.6493480615]
]], [[
    [4226201.053365226, 7697045.899310788],
    [4226164.317933269, 7697577.007928321],
   ...
    [4211359.938852671, 7621739.802166396],
    [4226201.053365226, 7697045.899310788]
]]
]}

а EsriJSON должен быть наподобие такого
«rings»: [
[
    [4279602.386113361, 7520773.048816763],
    [4279572.070031156, 7520668.786903687],
    [4279455.184565822, 7520710.387695587],
    [4279602.386113361, 7520773.048816763]
], [
    [4208589.216875655, 7569584.6493480615],
    [4208579.177972653, 7569396.323268423],
    [4207803.281121826, 7568963.732610181],
    [4208589.216875655, 7569584.6493480615]
], [
    [4226201.053365226, 7697045.899310788],
    [4226164.317933269, 7697577.007928321],
   ...
    [4211359.938852671, 7621739.802166396],
    [4226201.053365226, 7697045.899310788]
]]

Что любопытно, после того как я написал решение на Python, нашлось решение на JavaScript
exports.geoJsonToEsriGeometry = function (geoJsonGeometry) {
  var coordinates = geoJsonGeometry.coordinates;
  switch(geoJsonGeometry.type){
    case "Point":
      return { "x" : coordinates[0], "y" : coordinates[1] };
    case "MultiPoint":
      return {"points" : coordinates};
    case "LineString":
      return {"paths" : [coordinates]};
    case "MultiLineString":
      return {"paths": coordinates};
    case "Polygon":
      return {"rings" : coordinates};
    case "MultiPolygon":
      var result = [];
      for (var i = 0; i < coordinates.length; i++) {
        var polygon = coordinates[i];
        for (var j = 0; j < polygon.length; j++) {
          result.push(polygon[j]);
        }
      }
      return {"rings": result};
    default:
      return {"error": "failed to convert GeoJson : " + JSON.stringify(geoJsonGeometry)};
  }
};

Спецификации


original post http://vasnake.blogspot.com/2013/05/geojson-2-esrijson.html

Комментариев нет:

Отправить комментарий

Архив блога

Ярлыки

linux (241) python (191) citation (186) web-develop (170) gov.ru (159) video (124) бытовуха (115) sysadm (100) GIS (97) Zope(Plone) (88) бурчалки (84) Book (83) programming (82) грабли (77) Fun (76) development (73) windsurfing (72) Microsoft (64) hiload (62) internet provider (57) opensource (57) security (57) опыт (55) movie (52) Wisdom (51) ML (47) driving (45) hardware (45) language (45) money (42) JS (41) curse (40) bigdata (39) DBMS (38) ArcGIS (34) history (31) PDA (30) howto (30) holyday (29) Google (27) Oracle (27) tourism (27) virtbox (27) health (26) vacation (24) AI (23) Autodesk (23) SQL (23) humor (23) Java (22) knowledge (22) translate (20) CSS (19) cheatsheet (19) hack (19) Apache (16) Klaipeda (15) Manager (15) web-browser (15) Никонов (15) functional programming (14) happiness (14) music (14) todo (14) PHP (13) course (13) scala (13) weapon (13) HTTP. Apache (12) SSH (12) frameworks (12) hero (12) im (12) settings (12) HTML (11) SciTE (11) USA (11) crypto (11) game (11) map (11) HTTPD (9) ODF (9) Photo (9) купи/продай (9) benchmark (8) documentation (8) 3D (7) CS (7) DNS (7) NoSQL (7) cloud (7) django (7) gun (7) matroska (7) telephony (7) Microsoft Office (6) VCS (6) bluetooth (6) pidgin (6) proxy (6) Donald Knuth (5) ETL (5) NVIDIA (5) Palanga (5) REST (5) bash (5) flash (5) keyboard (5) price (5) samba (5) CGI (4) LISP (4) RoR (4) cache (4) car (4) display (4) holywar (4) nginx (4) pistol (4) spark (4) xml (4) Лебедев (4) IDE (3) IE8 (3) J2EE (3) NTFS (3) RDP (3) holiday (3) mount (3) Гоблин (3) кухня (3) урюк (3) AMQP (2) ERP (2) IE7 (2) NAS (2) Naudoc (2) PDF (2) address (2) air (2) british (2) coffee (2) fitness (2) font (2) ftp (2) fuckup (2) messaging (2) notify (2) sharepoint (2) ssl/tls (2) stardict (2) tests (2) tunnel (2) udev (2) APT (1) Baltic (1) CRUD (1) Canyonlands (1) Cyprus (1) DVDShrink (1) Jabber (1) K9Copy (1) Matlab (1) Portugal (1) VBA (1) WD My Book (1) autoit (1) bike (1) cannabis (1) chat (1) concurrent (1) dbf (1) ext4 (1) idioten (1) join (1) krusader (1) license (1) life (1) migration (1) mindmap (1) navitel (1) pneumatic weapon (1) quiz (1) regexp (1) robot (1) science (1) seaside (1) serialization (1) shore (1) spatial (1) tie (1) vim (1) Науру (1) крысы (1) налоги (1) пианино (1)