使用osm數據+postgreSQL+tegola+openlayers搭建輕量化矢量切片環境

tegola簡介

Tegola是一個矢量切片服務器,提供Mapbox Vector Tiles,支持PostGIS和GeoPackage數據提供程序。用戶文檔可以在tegola.io找到

tegola特徵

  • 原生幾何處理(簡化,裁剪,製作有效,交集,包含,縮放,翻譯)
  • 符合Mapbox Vector Tile v2規範。
  • 具有自動生成樣式的嵌入式查看器,可實現快速數據可視化
  • 支持PostGIS和GeoPackage數據提供程序。可擴展的設計,以支持其他數- 據提供商。
  • 支持多個緩存後端:file,s3,redis,azure blob store。
  • 通過單個切片(ZXY),緯度/經度邊界和ZXY切片列表緩存種子和失效。
  • 並行化的瓷磚服務和幾何處理。
  • 支持Web Mercator(3857)和WGS84(4326)預測。
  • 支持AWS Lambda。

導入osm數據

可以參考我前面的博文,使用最新編譯的osm2pgsql不用處理default.style中的註釋了,直接使用就可以了,我是用的是北京的數據,格式是pbf的。
最新版下載:https://ci.appveyor.com/project/openstreetmap/osm2pgsql

配置tegola的config.toml

參考官方配置說明,osm2pgsql導入數據的空間參考標識符 (SRID) 是3857不是經緯度的4326。
我的配置如下:

[webserver]
port = ":8080"

# register data providers
[[providers]]
name = "beijing"           # provider name is referenced from map layers
type = "postgis"        # the type of data provider. currently only supports postgis
host = "localhost"      # postgis database host
port = 5432             # postgis database port
database = "beijing"       # postgis database name
user = "postgres"         # postgis database user
password = "123456"           # postgis database password
srid = 3857             # The default srid for this provider. If not provided it will be WebMercator (3857)


  [[providers.layers]]
  name = "point"
  tablename = "planet_osm_point"  
  geometry_fieldname = "way"
  id_fieldname = "osm_id"
  fields = [ "name" ] 
  #sql = "SELECT name,ST_AsBinary(way) AS way,name,osm_id FROM planet_osm_point WHERE way && !BBOX!"

  [[providers.layers]]
  name = "road"
  geometry_fieldname = "way"
  id_fieldname = "osm_id"
  sql = "SELECT ST_AsBinary(way) AS way,name,osm_id FROM planet_osm_line WHERE way && !BBOX!"



[[maps]]
name = "beijing"

  [[maps.layers]]
  provider_layer = "beijing.point"
  min_zoom = 13
  max_zoom = 20

  [[maps.layers]]
  provider_layer = "beijing.road"
  min_zoom = 10
  max_zoom = 20

我這裏只配置了兩個圖層,一個點(point),13-20層顯示,一個線(road),10-20層顯示。

啓動tegola

在tegola所在目錄打開cmd,輸入 tegola serve 即可啓動

2019-04-18 09:04:18 [INFO] root.go:56: Loading config file: config.toml
2019-04-18 09:04:18 [INFO] config.go:173: loading local config (config.toml)
2019-04-18 09:04:19 [INFO] server.go:81: starting tegola server on port :8080

輸入tegola -h可以獲取幫助

編寫前端顯示html

<!DOCTYPE html>
<html>
  <meta charset="UTF-8" />
  <head>
    <title>Tegola Sample</title>
    <link rel="stylesheet" href="ol.css" type="text/css" />
    <script src="ol.js"></script>
    <style>
      #map {
        width: 1200px;
        height: 700px;
      }
    </style>
  </head>
  <body>
    <div id="map" class="map"></div>
    <div id="name" style="font-size: 24px;"></div>

    <script type="text/javascript">
      
      var defaultStyle = new ol.style.Style({
        fill: new ol.style.Fill({
          color: [234, 231, 221, 1]
        }),
        stroke: new ol.style.Stroke({
          color: [182, 177, 162, 1],
          width: 1
        })
      });
      var waterStyle = new ol.style.Style({
        fill: new ol.style.Fill({
          color: [28, 121, 181, 1]
        }),
        stroke: new ol.style.Stroke({
          color: [27, 107, 159, 1],
          width: 1
        })
      });
      var streetStyle = new ol.style.Style({
        fill: new ol.style.Fill({
          color: [111, 44, 173, 1]
        }),
        stroke: new ol.style.Stroke({
          color: [93, 32, 150, 1],
          width: 1
        })
      });
      var textStyle = new ol.style.Text({
        font: "normal 14px 微軟雅黑", //字體與大小
        fill: new ol.style.Fill({
          //文字填充色
          color: "#000"
        }),
        text: "text",
        stroke: new ol.style.Stroke({
          //文字邊界寬度與顏色
          color: "#fff",
          width: 3
        })
      });

      var initStyle = new ol.style.Style({
        fill: new ol.style.Fill({
          color: "rgba(255, 255, 255, 0.2)"
        }),
        stroke: new ol.style.Stroke({
          color: "red",
          width: 2
        }),
        image: new ol.style.Circle({
          radius: 8,
          stroke: new ol.style.Stroke({
            color: "red",
            width: 2
          })
        })
      });
      var xStyle = new ol.style.Style({
        image: new ol.style.RegularShape({
          fill: new ol.style.Fill({
            color: "red"
          }),
          stroke: new ol.style.Stroke({
            color: "red",
            width: 2
          }),
          points: 3,
          radius: 8,
          radius2: 0,
          angle: Math.PI / 3 + Math.PI
        })
      });

      function styleFunction(feature, resolution) {
        if (
          feature.get("type") == "water" ||
          feature.get("layer") == "lakes" ||
          feature.get("layer") == "water_lines"
        ) {
          return [waterStyle];
        }
        if (feature.get("layer") == "point") {
          return [xStyle, initStyle];
        }
        if (feature.get("layer") == "road") {
          return [streetStyle];
        }
        if (
          feature.get("layer") == "country_polygons" ||
          feature.get("layer") == "landuse_areas"
        ) {
          return null; // return null for no style to be applied
        }
        return [defaultStyle];
      }

      var map = new ol.Map({
        target: "map",
        layers: [
          new ol.layer.VectorTile({
            source: new ol.source.VectorTile({
              format: new ol.format.MVT(),
              url: "http://127.0.0.1:8080/maps/beijing/{z}/{x}/{y}.mvt"
            }),
            style: styleFunction
          })
        ],
        view: new ol.View({
          center: ol.proj.fromLonLat([116.41, 39.82]), //coordinates the map will center on initially
          zoom: 14,
          minZoom: 0,
          maxZoom: 20
        })
      });

      var scaleLineControl = new ol.control.ScaleLine({
        // 設置比例尺單位爲degrees、imperial、us、nautical或metric(度量單位)
        units: "metric"
      });
      map.addControl(scaleLineControl);
    </script>
  </body>
</html>

結果展示

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章