Search code examples
gisnetlogoshapefile

Restrict Turtle Movement to Boundary in NetLogo


In NetLogo, I'm looking to

  • have turtles sprout randomly within their boundaries on an imported shapefile and
  • restrict their movement to these boundaries

Currently, I have them sprouting at the centroid, but quickly they spread across the map. How can I incorporate the shapefile into the turtle's movement? Ideally, they would travel slightly outside their boundary, but I'm sure that's easy to manipulate after I restrict them. The turtles need to be able to interact with eachother across borders, just not travel across the whole map.

See this image for reference: MSOA File

A separate solution could be to restrict them within a radius of where they sprouted, but unsure of how to do that too.

I've considered:

  • creating different breeds, but it's much too tedious considering there must be a simpler solution
  • creating different colored patches and restricting their movement to their assigned-color patch, but that then limits their interaction (and again way too tedious)

Solution

  • What you want to do is to give patches two variables:

    1. One that identifies which region they belong to (I assume this already exists in your code, given that you import a shapefile);
    2. Another one that identifies the patch's own region + regions that are close enough that a turtle from the other region might move there.

    I'll call the first variable region and it will be an integer, the second variable allowed and it will be a list of integers.

    The idea is that turtles, each of which has its own my-region value based on where it originated from, will look at the allowed patch-variable (and not at region) to see where they can move. That way, each turtle will be able to move to any patch belonging to its own region + to those patches that are close enough to its region (according to a value that you specify, which here I called buffer-range).

    This is the logic.

    The code below implements it, the relevant part being to create-buffers - which I commented in-code. Then, to go uses this new information to determine the potential patches where the turtle can move, including those outside its region but close enough (you did not share how your turtles move, but it should be easy to apply the same condition to whatever procedure you are implementing).

    ; Untick the 'World wraps horizontally' box in Interface > Settings.
    
    globals [
     buffer-range
    ]
    
    patches-own [
     region
     allowed
    ]
    
    turtles-own [
     my-region 
    ]
    
    to setup
      clear-all
      create-regions
      create-buffers
      populate-world
    end
    
    to create-regions
      ask patches [
       ifelse (pxcor < 0)
        [set region 1
         set allowed (list region)
         set pcolor 43]
        [set region 2
         set allowed (list region)
         set pcolor 63]
      ]
    end
    
    to create-buffers
      set buffer-range 3
      
    ; First, each patch targets the patches that belong to another region which is near enough according to
    ; the buffer value, and it also creates a local empty list that will be used by those patches.
    ; Then the patch ask those target patches, if any, to check if their region has not been recorded already
    ; as a region allowed for movement or as such a candidate. If that's the case, that region is added to
    ; the allowed-candidates list.
      ask patches [
        let target-patches (patches with [region != [region] of myself] in-radius buffer-range)
        let allowed-candidates (list)
        
        if (any? target-patches) [
          ask target-patches [
           if (not member? region [allowed] of myself) and (not member? region allowed-candidates) [
             set allowed-candidates (lput region allowed-candidates)
            ]
          ]
        ]
        
    ; Now, each element of the allowed-candidates list is added to the allowed list.
        foreach allowed-candidates [x -> set allowed (lput x allowed)]
      ]
    end
      
    to populate-world
      create-turtles 10 [
        setxy random-xcor random-ycor
        set my-region region
        set color pcolor + 2
      ]
    end
    
    to go
      ask turtles [
        move-to one-of patches with [member? [my-region] of myself allowed]
      ]
    end
    

    For future questions, please share what you have / what you did (check here and here)! Ideally, you should provide an example of your problem that is like the code part of my answer: you can copy-paste it in NetLogo and you have a workable example.