0

I am still quite new to mapping, and am trying to implement an offline-solution with either leaflet or OpenLayers (I managed to implement an online example which works). I am trying this using vue.

What I was trying was to generate data with maperative, which then produced a tiles directory, which contains a tiles.json file and directories called 6, 7, 8, 9 and 10, which contain more directories which contain png files with map data.

Can someone tell me what I am doing wrong, or show me a little example code how I can display map data from maperative with either vue leaflet or vue openlayers?

I tried modifying some code I found elsewhere like this:

<template>
 <l-map
   :center="center"
   :zoom="zoom"
   class="map"
   ref="map"
   @update:zoom="zoomUpdated"
   @update:center="centerUpdated"
 >
   <l-tile-layer
     :url="url"
   >
   </l-tile-layer>
   </l-map>
</template>
<script>
import { LMap, LTileLayer } from 'vue2-leaflet';
import 'leaflet/dist/leaflet.css';
export default {
 components: {
   LMap,
   LTileLayer
 },
 data () {
   return {
     url: 'file:////home/user/FD/workspace/features/ol-vue-example-master/harvest_assist_ui/src/assets/Tiles/${z}/${x}/${y}.png',
     center: [ 50.4193089, 40.6757156 ],
     zoom: 12,
   }
 },
 methods: {
   zoomUpdated (zoom) {
     this.zoom = zoom;
     console.log(this.markers)
   },
   centerUpdated (center) {
     this.center = center;
   }
 }
}
</script>

<style>
 .map {
   position: absolute;
   width: 100%;
   height: 100%;
   overflow :hidden
 }
</style>
for Leaflet, and I tried this for OpenLayers:
<template>
<div style="width: 100%; height: 100%">
            <button style="width: 10%; height: 10%" type="button" id="idSubmit" name="Set All" @click="SetAll" class="btn">Apply</button>
  <div ref="map-root"
       style="width: 90%; height: 90%">
  </div>
  </div>
</template>

<script>
  import View from 'ol/View'
  import Map from 'ol/Map'
  import TileLayer from 'ol/layer/Tile'
  import OSM from 'ol/source/OSM'
  import VectorLayer from 'ol/layer/Vector'
  import VectorSource from 'ol/source/Vector'
  import GeoJSON from 'ol/format/GeoJSON'

  import 'ol/ol.css'

  export default {
    name: 'MapContainer',
    components: {},
    props: {
      geojson: Object
    },
    data: () => ({
      olMap: null,
      source: null,
      vectorLayer: null,
      selectedFeature: null
    }),
    mounted() {
      this.vectorLayer = new VectorLayer({
        source: new VectorSource({
          features: [],
        }),
      })

      this.source = new OSM();
            var MyLayer = new OSM("mymap","file:///home/user/FD/workspace/features/ol-vue-example-master/src/assets/Tiles/${z}/${x}/${y}.png", {numZoomLevels: 16, alpha: true, isBaseLayer: true, visibility: false});
      this.olMap = new Map({
        target: this.$refs['map-root'],
        layers: [
          new TileLayer({
            source: this.source,
          }),
          this.vectorLayer
        ],
        view: new View({
          zoom: 0,
          center: [0, 0],
          constrainResolution: true
        }),
      })
      this.olMap.layers = MyLayer;
      console.debug(MyLayer);       
      this.olMap.on('pointermove', (event) => {
        const hovered = this.olMap.forEachFeatureAtPixel(event.pixel, (feature) => feature)
        if (hovered !== this.selectedFeature) {
          this.$set(this, 'selectedFeature', hovered);
        }
      })

      this.updateSource(this.geojson)
    },
    watch: {
      geojson(value) {
        this.updateSource(value)
      },
      selectedFeature(value) {
        this.$emit('select', value)
      }
    },
    methods: {
      SetAll() 
      {
         console.debug("Test");
         console.debug(this.source);
         var osmextent = this.vectorLayer.getSource().getExtent();
         var currentzoom = this.olMap.getView().zoom;
         console.log(this.vectorLayer.getSource());
         //var osmzoom = this.vectorLayer.getSource().getZoom();
         var osmzoom = currentzoom;
         console.debug("BLA");
         console.debug(osmextent);
         console.debug(currentzoom);
         console.debug(osmzoom);
    this.source.getTileGrid().forEachTileCoord(osmextent,parseInt(osmzoom), function(tileCoord)
         {
                      console.debug("BLUBB2");
           var img = document.createElement("img");
           img.onload = function() 
           {
             var canvas = document.createElement("canvas");
             canvas.width = this.source.getTileGrid().getTileSize(currentzoom);
             canvas.height = this.source.GetTileGrid().getTileSize(currentzoom);
             var ctx = canvas.getContext("2d");
             ctx.drawImage(img, 0, 0);
             localStorage.setItem('OSM_' + tileCoord[0]+'_'+tileCoord[1]+'_'+(-tileCoord[2]-1), canvas.toDataURL());
             console.debug('OSM_' + tileCoord[0]+'_'+tileCoord[1]+'_'+(-tileCoord[2]-1), canvas.toDataURL());
             img.remove();
             canvas.remove();
             console.debug("BLUBB");
           }
           img.crossOrigin = "Anonymous";
           img.src = this.source.getTileUrlFunction()(tileCoord);
         });
         
      },
      updateSource(geojson) {
        const view = this.olMap.getView();
        const source = this.vectorLayer.getSource();

        const features = new GeoJSON({
          featureProjection: 'EPSG:3857',
        }).readFeatures(geojson);

        source.clear();
        source.addFeatures(features);

        view.fit(source.getExtent())
      }
    }
  }
</script>
11
  • Any errors in the browse debugger console? For security reasons I doubt you can access tile from your local file system.
    – TomazicM
    Aug 1 at 10:20
  • Yes, it gave an error about security "Security Error: Content at localhost:8080 may not load or link to file:///home/user/FD/workspace/features/ol-vue-example-master/harvest_assist_ui/src/assets/Tiles/$12/$2513/$1382.png". If I cannot acess a tile from the local file system, how can I access it then ? Over some kind of database I assume ? Thanks in advance!
    – MagicSN
    Aug 1 at 12:13
  • Simplest way would be over local web server. This means you have to put your tiles inside your local web server so they are accessible through it. And I doubt your tile names start with $ character, so you have to leave it out in your tile access address.
    – TomazicM
    Aug 1 at 12:33
  • I'd recommend using relative URLs instead of absolute URLs (no need to have a local webserver that way, IIRC). Do read developer.mozilla.org/en-US/docs/Learn/Common_questions/… if you need a refresher on the subject. Aug 1 at 13:08
  • Yeah, the stuff with the $ was what the code appearently made out of what I typed. In the source-code it was written like that "file:///home/user/FD/workspace/features/ol-vue-example-master/harvest_assist_ui/src/assets/Tiles/${z}/${x}/${y}.png". The directory with the Tiles looks like Tiles/tiles.json Tiles/6 Tiles/7 Tiles/8 Tiles/9 Tiles/10. What exactly is the path I need to give to the library ? Thanks in advance! (thanks for the refresher @IvanSanchez also, I will read this)
    – MagicSN
    Aug 1 at 13:51

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.