4

So recently I am doing a small challenge with Vue.js and OpenLayers 5.

The first step I want to do is create a simple Open street map and put my own GPS data as vector layer onto it.

Things are going well until I got some issue with the "path" in Vue.js single file component.

Below is what the child component looks like (for the GPS vector layer generation):

<template>
  <div>
      <input type="button" value="addGPXData" @click="addData"/>
  </div>
</template>

<script>
import Map from 'ol/Map.js';
import {Circle as CircleStyle, Fill, Stroke, Style} from 'ol/style.js';
import VectorSource from 'ol/source/Vector.js';
import {Tile as TileLayer, Vector as VectorLayer} from 'ol/layer.js';
import GPX from 'ol/format/GPX.js';

export default {
  name: 'addGPXData',
  props: ['map'],
  data () {
    return {

    }
  },
  mounted () {

  },
  methods: {
    addData: function() {
        console.log('addData_map: ', this.map);

        var style = {
            'Point': new Style({
                image: new CircleStyle({
                    fill: new Fill({
                        color: 'rgba(255,255,0,0.4)'
                    }),
                    radius: 5,
                    stroke: new Stroke({
                        color: '#ff0',
                        width: 1
                    })
                })
            }),
        };

        var vector = new VectorLayer({
            source: new VectorSource({
                //url: '.././assets/2018-08-05_17-22-37.gpx',
                //url: '.././assets/test.gpx',
                url: 'https://openlayers.org/en/v4.6.2/examples/data/gpx/fells_loop.gpx',
                crossOrigin: 'anonymous',
                format: new GPX()
            }),
            style: style['Point']
        });

        this.map.addLayer(vector);
    }
  }
}
</script>

Please notice the three lines of URL in VectorSource

The line I left there is the only URL (with https://) that works, it is an URL from OpenLayers itself for the example and demo.

I downloaded the .gpx file from the official and renamed it to test.gpx together with my own GPS file 2018-08-05_17-22-37.gpx. I put them to the default assets folder. The structure of my file system seems like this (I didn't change it, it was originally created by Vue-cli):

--src
  --assets
    --2018-08-05_17-22-37.gpx
    --test.gpx
  --components
    --addGPXData.vue
    --mapContainer.vue
  --App.vue
  --main.js

I would like to know what is wrong with these two lines of URL which I commented out? I have read the official document and I understand for those situations, a relative path, which begins with "." need to be used. I did that, but it still doesn't work. How should I write the path for local files?

The official document for the static assets and path:

https://cli.vuejs.org/guide/html-and-static-assets.html#static-assets-handling

update:

I have already tried the given advises, thank you for all you guys that helped, but nothing works at the moment. either ../, @ or import

and I started to read the document of OpenLayers, which I find, quite interesting:

OpenLayers will the URL and make an XMLHttpRequest to load the GPX file. And I think that is the problem here. Because I think we can't make XMLHttpRequest in Vue to get a local file. Because all the files will be compiled first and at the end, we don't have a path like '../asset/x.gpx'.

I don't know if I understand that right. I would also ask what will the file system look like after it all being compiled?

The final update

Today I solved this problem by putting the GPX file to the public folder and use Vue-resource (GET) to get it, the codes look like below:

    // get the GPX file
    this.$http.get(self.selectedGPX + '.gpx').then(response => {
        var GPXString = response.body;
    }, response => {
        //error callback
        console.log('Http request get error');
    });

on the OpenLayers side, I just used the solution 2 from the question which is marked as duplicated. I no more use the URL option and choose to load the GPX file with Vue-resource as String and parse it, at the end add the parsed features to the empty vector layer.

Min XIE
  • 463
  • 8
  • 19
  • Either "../assets/test.gpx" or "@/assets/test.gpx" should work. – Daniel Beck Sep 05 '18 at 16:49
  • @DanielBeck thank you for the advise, I have tried both. But I got a weird error which says **xml parser error. ... expected: ** – Min XIE Sep 05 '18 at 17:22
  • That sounds like it's finding the .gpx file correctly, and reporting an error inside it. (I don't know anything about the .gpx format, but it's XML, and you're getting an XML parser error, so that pretty strongly suggests that's where the problem is.) You may want to open a separate question for that, since it's unrelated to the relative-path question you asked here. – Daniel Beck Sep 05 '18 at 18:04
  • I have serached a lot and I am pretty sure it is a path issue. Please see my update part in the question description. – Min XIE Sep 05 '18 at 18:10
  • I vote to reopen due to the effort made by the OP to improve the question – xenteros Sep 06 '18 at 16:35

2 Answers2

1

Your component is nested one folder deep (/components/addGPXData.vue), so you need only ../ to get back to /assets directory. From my understanding your url has to be ../assets/2018-08-05_17-22-37.gpx

Jns
  • 3,189
  • 1
  • 18
  • 23
  • thank you for the advise, I have tried the `../` path and this time I got the error message in the console: **xml parser error. ... expected ** – Min XIE Sep 05 '18 at 17:20
1

I think you can solve this importing the file:

    import gpx from '../assets/2018-08-05_17-22-37.gpx',

    var vector = new VectorLayer({
        source: new VectorSource({
            url: gpx,
            crossOrigin: 'anonymous',
            format: new GPX()
        }),
        style: style['Point']
    });

Make sure that webpack is using file-loader on gpx files.

on your vue.config.js:

module.exports = {
  configureWebpack: {
    module: {
        rules: [{
            test: /\.gpx$/i,
            use: [{
                loader: 'file-loader'
            }]
        }]
    }
  }
}
lmarqs
  • 1,469
  • 13
  • 16
  • I have tried to import the gpx file, but unluckly I got the error message: `Module parse failed: Unexpected token (1:0) You may need an appropriate loader to handle this file type.` – Min XIE Sep 05 '18 at 17:18
  • @MinXIE, It means that `url-loader`is not being used to parse the file. Is the `url-loader` that will parse the `import` to the correct url. Can you put your `vue.config.js` in the question? – lmarqs Sep 05 '18 at 17:26
  • I searched quickly for the vue.config.js, the documetation says it should be next to my `package.json`. But actually I don't have that file. I don't know what is wrong. I am really a beginner for that. Should I create one? – Min XIE Sep 05 '18 at 17:32
  • `vue.config.js`was introduced on vue-cli 3. If there is no `vue.config.js` file probably the project was not created using it and there is a `webpack.conf.js` or `webpack.base.conf.js` file. How was the project initialized? Is there such file? – lmarqs Sep 05 '18 at 17:40
  • The project was created by using the vue-cli 3 today. The defaut setting was used by the creation. I got `gitignore`, `babel.config.js`, `package-lock.json` and `package.json` below the src folder. – Min XIE Sep 05 '18 at 17:42
  • Ok, I edited my answer. Create a `vue.config.js` on the root of your project (same directory as package.json) and put the code I put in my answer. I tested it here and worked fine. – lmarqs Sep 05 '18 at 18:15
  • Sry, I tried what u said but it still doesn't work. I think maybe it will be better if I check the Webpack documentation first. By the way, is Webpack automaticlly installed when I use vue cil 3 to create a new project? I am kinda confused with webpack-things here – Min XIE Sep 05 '18 at 18:24
  • What do you mean with 'doesn't work'? Is there some error message? Yes, if you look at the `npm_modules` you will see that `webpack` and `url-loader` is already installed. – lmarqs Sep 05 '18 at 18:29
  • I checked the `npm_modules` and it has the `webpack` and `url-loader` installed. It still doesn't work means the error message is the same: **./src/assets/test.gpx 1:0 Module parse failed: Unexpected token (1:0) You may need an appropriate loader to handle this file type.** Also pls see my update info, which I consider could be the issue – Min XIE Sep 05 '18 at 18:43
  • Take a look on this sample... I using `file-loader` instead of `url-loader`. https://github.com/lmarqs/vue-gpx. – lmarqs Sep 05 '18 at 19:51