gipong / shp2geojson.js

Convert shapefile to geoJSON via a web browser without Server-Side code. This conversion will unzip your file and reproject the data with correct encoding in JavaScript.
http://gipong.github.io/shp2geojson.js/
MIT License
256 stars 90 forks source link

Openlayers 3 #4

Open grwhumphries opened 7 years ago

grwhumphries commented 7 years ago

I'm a big fan of this JS, however I'm curious as to if there's a way to integrate this into openlayers 3. I'm a bit of a n00b to JS programming, and if an ol3 example exists, that would be greatly helpful.

gipong commented 7 years ago

Hi, I try to integrate this into openlayers 3 (version 3.18.1). For this version you can add geojson layer like this

var map = new ol.Map({
    layers: [
        new ol.layer.Tile({
            source: new ol.source.OSM()
        })
    ],
    target: 'map',
    view: new ol.View({
        center: [0, 0],
        zoom: 5
    })
});

loadshp({
    url: 'demo/10tnvillage.zip',
    encoding: 'big5',
    EPSG: 3826
}, function(data) {
    var feature = new ol.format.GeoJSON().readFeatures(data, {
        featureProjection: 'EPSG:3857'
    });
    var layer = new ol.layer.Vector({
        source: new ol.source.Vector({
            features: feature
        })
    });
    map.addLayer(layer);

    var extent = layer.getSource().getExtent();
    map.getView().fit(extent, map.getSize());
});
grwhumphries commented 7 years ago

Thanks, that's very helpful.
Is there a way to "unload" the shp file? What is happening is that when I run this, and then use map.removeLayer(layer), and then RErun it, it loads two polygons. Seems like it is not dropping the data from "layer"

gipong commented 7 years ago

I think map.removeLayer(layer_reference) is a good way to remove the feature on map. May be the problem is the removeLayer function argument can't reference to the correct layer. You can also check the layer is ol3 object or undefined before you call the map.removeLayer().

andrewrobot commented 7 years ago

@grwhumphries Did you find a solution to this? I'm having the exact same issue

grwhumphries commented 7 years ago

@andrewrobot unfortunately not - the removeLayer function still doesn't quite do it - so I had to set it up so the user refreshes the page after a polygon has been drawn.

gipong commented 7 years ago

if anyone can share the code snippet in your project, pls let me know.

Morgul commented 7 years ago

@grwhumphries The problem is that ol3 actually holds on to the layers (even after 'removeLayer') and (in your case, more importantly) the source. So, what you really need to do is not remove the layer, but clear the source.

Here's a modified example, off the top of my head:

// Store the map
var shapeLayer = new ol.layer.Vector({ new ol.source.Vector() })

// Initial map
// Store the map
var shapeLayer = new ol.layer.Vector({ new ol.source.Vector() })

// Initial map
var map = new ol.Map({
    layers: [
        new ol.layer.Tile({ source: new ol.source.OSM() }),
        shapeLayer
    ],
    target: 'map',
    view: new ol.View({
        center: [0, 0],
        zoom: 5
    })
});

function zoomToExtent()
{
        var extent = layer.getSource().getExtent();
        map.getView().fit(extent, map.getSize());
}

function loadShape()
{
    // load the shape file
    loadshp({
            url: 'demo/10tnvillage.zip',
            encoding: 'big5',
            EPSG: 3826
        },
        function(data)
        {
            var features = new ol.format.GeoJSON().readFeatures(data, { featureProjection: 'EPSG:3857' });

            // Add feature to the source. If you want to, you can even track this feature collection, and remove 
            // just these features later.
            shapeLayer.getSource().addFeatures(features);

            zoomToExtend();
        });
}

function clearShapes(features)
{
    if(features)
    {
        // We remove the features we were just told to remove
        features
            .forEach(function(feature)
            {
                shapeLayer.getSource().removeFeature(feature);
            });

        zoomToExtent();
    }
    else
    {
        // We remove all features
        shapeLayer.getSource().clear();
    } // end if
}
kuo-cheng-wu commented 6 years ago

To prevent the double loading after the 2nd run you can refresh the inputData by adding one line into the loadshp function: function loadshp(config, returnData) { inputData = {}; ...