Window Functions

نمایش یک Shapefile بر روی نقشه با استفاده از Openlayers

در این یادداشت به صورت گام به گام مراحل لازم برای نمایش اطلاعات یک Shapefile بر روی یک نقشه با استفاده از Openlayers را شرح می دهیم و سپس نحوه تبدیل این اطلاعات به فرمت Vector Tile برای افزایش بازدهی را توضیح می دهیم.

سیستم اطلاعات جغرافیایی, سامانه اطلاعات جغرافیایی,سامانه اطلاعات مکانی, نرم افزار, ژئوپرتال, GIS, WebGIS, Web-GIS,Software, GIS-Software, Geoportal, Mobile-GIS, Openlayers, GDAL, OGR,OGR2OGR, Geojson, Shapefile, Toturial, Vector, Vector Tile

ساده ترین راه برای انتشار و نمایش عوارض موجود در یک Shapefile، تبدیل آن به فرمت GeoJSON و سپس استفاده از ابزارهای نمایش نقشه برای ترسیم عوارض است.
برای تبدیل Shapefile به فرمت GeoJSON می توان از ابزارهای مختلف تجاری و رایگان و همچنین سایت های آنلاین استفاده کرد.
در زیر نحوه تبدیل یک شیپفایل با استفاده از کتابخانه مجانی GDAL/OGR نشان داده شده است.

ogr2ogr -f GeoJSON parcel.json parcel.shp -t_srs EPSG:4326

پس از آماده کردن GeoJSON می توان از یکی از کتابخانه های نمایش نقشه مثل Leaflet، Openlayers، Google Maps، ArcGIS API for JavaScript، Mapbox و ... استفاده کرد. در ادامه نحوه نمایش داده های مکانی نمونه با استفاده از Opnelayers تشریح می شود.

Openlayers

برای استفاده از این کتابخانه می توانید شبیه زیر لینک های مربوط به کتابخانه JavaScript و CSS آن را در صفحه وب خود اضافه کنید:


<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>GeoJSON Sample</title>
    <link href="/lib/openlayers/ol.css" rel="stylesheet"/>
    <script type="text/javascript" src="/lib/openlayers/ol.js"></script>
  </head>
  <body>
    <div id="map1" style="width: 600px; height: 400px;"></div>
    <script>
       // initialize map 
        var map = new ol.Map({target: 'map1',...});
    </script>   
  </body>
</html>

کد زیر یک نقشه با یک لایه OpenStreetMap را که در محدوده ایران زوم شده است را نشان می دهد:

var map = new ol.Map({
     layers: [
         new ol.layer.Tile({
             source: new ol.source.OSM({
                 maxZoom: 18
             })
         })
     ],
     target: 'map1',
     view: new ol.View({
         center: ol.proj.fromLonLat([53, 33]),
         maxZoom: 18,
         zoom: 5
     })
   });   

نقشه

افزودن GeoJSON به نقشه

در صورتی که فایل GeoJSON شما از طریق یک آدرس Url قابل دسترس باشد می توانید شبیه زیر فایل مورد نظر را به صورت یک لایه به نقشه قبل اضافه کنید.


 var geoJsonSource=new ol.source.Vector({
                format: new ol.format.GeoJSON(),
                url: '/data/geojson/parcel.json',
        });
  map.addLayer(new ol.layer.Vector({
            source: geoJsonSource
          }));       

بارگذاری GeoJSON و افزودن به صورت یک لایه

می توانید محتویات متنی GeoJSON را مستقیما به صورت یک شی JavaScript استفاده کنید. در این صورت برای بارگذاری اشکال هندسی می توانید به شکل زیر عمل کنید.

var geojsonObject = {
  'type': 'FeatureCollection',
  'crs': {
    'type': 'name',
    'properties': {
      'name': 'EPSG:3857',
    },
  },
  'features': [
    {
      'type': 'Feature',
      'geometry': {
        'type': 'Point',
        'coordinates': [0, 0],
      },
    },
    ...
  ]
}
var geoJsonSource=new ol.source.Vector();
geoJsonSource.addFeatures(new ol.format.GeoJSON().readFeatures(geojsonObject));
map.addLayer(new ol.layer.Vector({
            source: geoJsonSource
          }));

برای رنگامیزی عوارض می توان از Style به شکل زیر استفاده کرد.

var polygonStyle= new ol.style.Style({
        stroke: new ol.style.Stroke({
            color: 'blue',
            width: 1,
        }),
        fill: new ol.style.Fill({
            color: 'rgba(0,255,255, 0.5)',
        }),
    }); 
.
.
.
map.addLayer(new ol.layer.Vector({
            source: geoJsonSource,
            style: polygonStyle

          }));

رنگامیزی عوارض

دسته بندی عوارض

در صورت نیاز به دسته بندی یا رنگآمیزی براساس یکی از خصوصیات عارضه می توان به جای یک استایل ثابت از یک تابع که براساس شرایط مورد نظر استایل مناسب هر عارضه را محاسبه می کند استفاده کرد. برای مثال در اینجا به ازای مقادیر مختلف خصوصیت Landuse_Gr انواع مختلفی استایل می سازیم و سپس توسط یک تابع، استایل مناسب را انتخاب می کنیم:

var landuseClasses={
        'default':new ol.style.Style({
            stroke: new ol.style.Stroke({
                color: 'blue',
                width: 1,
            }),
            fill: new ol.style.Fill({
                color: 'rgba(0,255,255, 0.5)',
            }),
        }),
        '1':new ol.style.Style({
            stroke: new ol.style.Stroke({
                color: 'blue',
                width: 1,
            }),
            fill: new ol.style.Fill({
                color: 'rgba(255,0,0, 0.5)',
            }),
        }),
        '2':new ol.style.Style({
            stroke: new ol.style.Stroke({
                color: 'blue',
                width: 1,
            }),
            fill: new ol.style.Fill({
                color: 'rgba(0,255,0, 0.5)',
            }),
        }),
        .
        .
        .

    };
var styleFunction = function (feature) {
        var groupKey=feature.get('Landuse_Gr');
        var groupStype= landuseClasses[groupKey] || landuseClasses['default'];
        return groupStype;
   }; 
 map.addLayer(new ol.layer.Vector({
            source: geoJsonSource,
            style: styleFunction
          }));

دسته بندی عوارض

استفاده از Vector Tiles

با وجود سادگیِ GeoJSON، استفاده از این فرمت برای داده های حجیم مشکلات زیر را دارد:

  • لزوم دانلود اصل اطلاعات
  • حجم زیاد اطلاعاتی که باید بر روی مرورگر دانلود شود
  • مصرف زیاد حافظه و قدرت پردازش کامپیوتر کاربر برای نمایش اطلاعات بُداری بر روی مرورگر

یکی از راه های دور زدن این مشکلات استفاده از قدرت سرور میزبان برای ترسیم یا اصطلاحا رندر نقشه و ارسال تصویر نقشه به مرورگر است که در صورتی که اطلاعات نقشه برای مدت زمان مشخص ثابت باشند می توان حتی پروسه ترسیم را هم به صورت مجزا انجام داد و فقط تصویر یا تصاویر موزایکی نقشه را به صورت آماده برای دانلود نگهداشت.
راه دیگر برای دور زدن مشکلات مطرح شده، ارسال فقط بخشی از اطلاعات (که متناسب با بزرگنمایی و محدوده جاری نقشه نیاز به ترسیم دارد)، به مرورگر است. برای این کار از فرمت Vector Tile استفاده می شود. در این فرمت اطلاعات برداری از قبل برای زوم های مختلف ساده سازی و فشرده سازی می شود و به صورت مجزا به مرورگر انتقال داده می شود. یکی از این نوع فرمت ها ، فرمت MVT است.
داده های MVT را می توان درون یک پایگاه داده Sqlite ذخیره کرد یا اینکه مستقیم فایل هر Tile را در یک فایل pbf در یک ساختار فولدر بندی شده نگهداری کرد. برای دسترسی به هر فایل یک آدرس بر اساس مشخصات سطح بزرگنمایی (z) و اندکس های x و y تایل مورد نیاز است.
برای تبدیل یک فایل GeoJSON به فرمت MVT می توان از GDAL/OGR به صورت زیر استفاده کرد:


ogr2ogr -f MVT output_folder inputGeoJSON.json -dsco MINZOOM=0 -dsco MAXZOOM=18 -dsco TILE_EXTENSION=pbf

در این فرمان به جای output_folder نام یا مسیر فولدر خروجی و به جای inputGeoJSON.json نام یا مسیر فایل ورودی را جایگزین کنید.

برای افزودن این اطلاعات به نقشه می توانید به صورت زیر عمل کنید:


 var vectorTileSource =new ol.source.VectorTile({
                format: new ol.format.MVT(),
                url: '/data/mvt/parcel_tiles/{z}/{x}/{y}.pbf'
        });
 var vectorTileLayer=new ol.layer.VectorTile({
            source: vectorTileSource
          });
 map.addLayer(vectorTileLayer);        

MVT