How to handle large GIS shapefiles?

62 views Asked by At

I am building a model in netlogo and have quite a detailed habitats map where the file size is 68mb (67,928 KB) - I simplified the vertices and reduced the file to 47mb (46,958 KB) however it still crashes netlogo when I try to import the file.

What would you recommend -either from a preprocessing approach or a netlogo approach- to improve either the file size or netlogo's ability to handle it?

My code to load it in is

extensions [gis csv]
globals [world world-shape]
patches-own [habitat]

to set-up
  clear-all
  reset-ticks
  gis:load-coordinate-system "Habitat_map_Pflugmacher_20km_buffer.prj"
      set world gis:load-dataset "Habitat_map_Pflugmacher_20km_buffer.shp"
 ;; load in the circle around the island to create a buffer
  set world-shape gis:load-dataset "Habitat_map_Pflugmacher_20km_buffer.shp"  gis:set-drawing-color white
  gis:set-world-envelope-ds gis:envelope-of world-shape
  gis:apply-coverage world "Gridcode" habitat

        foreach gis:feature-list-of world
  [ ?1 ->
    if gis:property-value ?1 "Gridcode" = 1 [ gis:set-drawing-color 6  gis:fill ?1 2.0] ;; artificial land
    if gis:property-value ?1 "Gridcode" = 2[ gis:set-drawing-color 46  gis:fill ?1 2.0] ;; seasonal crops
    if gis:property-value ?1 "Gridcode" = 3 [ gis:set-drawing-color 43  gis:fill ?1 2.0] ;; perrenial crps
    if gis:property-value ?1 "Gridcode" = 4 [ gis:set-drawing-color 57  gis:fill ?1 2.0] ;; broadlead forest
     if gis:property-value ?1 "Gridcode" = 5 [ gis:set-drawing-color 52  gis:fill ?1 2.0] ;; conifer forest
        if gis:property-value ?1 "Gridcode" = 12  [ gis:set-drawing-color 55  gis:fill ?1 2.0] ;; mixed forest
    if gis:property-value ?1 "Gridcode" = 6 [ gis:set-drawing-color 63 gis:fill ?1 2.0] ;; shrubland
    if gis:property-value ?1 "Gridcode" = 7 [ gis:set-drawing-color 65  gis:fill ?1 2.0] ;; grassland
    if gis:property-value ?1 "Gridcode" = 8 [ gis:set-drawing-color 35  gis:fill ?1 2.0] ;; bareland
    if gis:property-value ?1 "Gridcode" = 9  [ gis:set-drawing-color 95  gis:fill ?1 2.0] ;; water
    if gis:property-value ?1 "Gridcode" = 10 [ gis:set-drawing-color 85  gis:fill ?1 2.0] ;; wetland
     if gis:property-value ?1 "Gridcode" = 11 [ gis:set-drawing-color 68  gis:fill ?1 2.0] ;; wetlands
    if gis:property-value ?1 "Gridcode" = 12  [ gis:set-drawing-color 9.9  gis:fill ?1 2.0] ;; snow    ]
  ]
2

There are 2 answers

0
Steve Railsback On

What do you mean by "crash NetLogo"? Does it just never finish, or do you actually get an error message? If so, what is it?

Make sure you are aware of the memory allocation issue-- If not, open the FAQ section of the User Manual and look for the question "How big can my model be?"

If you are not sure what's going on, you could put a "show" statement inside the foreach loop to tell you which feature it's working on.

(I've never tried to import such a big shapefile but in theory it should work.)

0
Pol On

I am not sure if this will be enough to achieve what you want, but I suggest you to try

to set-up
  clear-all
  reset-ticks
  
  gis:load-coordinate-system "Habitat_map_Pflugmacher_20km_buffer.prj"
  
  set world gis:load-dataset "Habitat_map_Pflugmacher_20km_buffer.shp"
  
  ;; load in the circle around the island to create a buffer
  gis:set-world-envelope-ds gis:envelope-of world
  gis:apply-coverage world "Gridcode" habitat
  
  let girdcodes [1   2   3   4   5   6   7   8   9   10   11   12]
  let colors    [6  46  43  57  52  63  65  35  95   85   68  9.9]
  
  (foreach (gis:feature-list-of world) girdcodes colors [ [?1 gc c] ->
    if gis:property-value ?1 "Gridcode" = gc [gis:set-drawing-color c gis:fill ?1 2.0]
    ]
  )
end

The main thing here is removing world-shape, as you were loading again a the large shapefile you are using. I believe that doing the same with just the world global should work and you save NetLogo from loading that two times. Also removed gis:set-drawing-color white as you were not actually drawing anything after setting that color.

A minor improvement is colouring with a foreach handling multiple lists approach. I don't think this is key in solving your problem, but makes your code clearer (i removed on of the girdcodes with value equal to 12, as it was repeated).