Misaligned between imported GIS files and network (nodes have X and Y coordinates) - NetLogo - gis

I, once again have a question. My previous solution to my problem didn't work as I expected. To remind you, I imported some polygons and had a problem setting some turtles (cities) in the NetLogo world appropriately (to read GIS coordinates from non-gis file and set their position in the world, more on Netlogo doesen't recognize the GIS coordinates in the defined envelope of the world, it treats them as netologo world coordinates). So, in the end, I came up with a solution to transform the GIS coordinates in NetLogo coordinates (nl-x and nl-y procedures). The cities are actually in graphml format with x and y attributes. So, my code is this:
extensions [nw gis]
directed-link-breed [highways highway]
breed [cities city]
highways-own [ name ]
cities-own [ x y ]
globals [ paldrino ]
to setup
ca
;; set the world envelope
gis:load-coordinate-system "wgs84.prj"
set paldrino gis:load-dataset "paldrino.shp"
let world ( gis:envelope-of paldrino )
gis:set-world-envelope (world)
;; Make them visible
foreach gis:feature-list-of paldrino [ ;for each polygon
polygon ->
let temp-color one-of base-colors
ask patches gis:intersecting polygon [
set pcolor temp-color
]]
;; load network
nw:set-context cities highways
nw:load-graphml "highway-network.graphml"
ask cities[
set xcor nl-x(read-from-string x) ;; if I put set xcor read-from-string x, then it will put all the nodes in one point in Netlogo world, same for setxy fix-x(read-from-string x) fix-y (read-from-string y)
set ycor nl-y (read-from-string y)
]
end
to-report nl-x [#x]
let world gis:envelope-of paldrino
let minx item 0 world
let maxx item 1 world
report ((#x - minx) / (maxx - minx)) * (max-pxcor - min-pxcor) + min-pxcor
end
to-report nl-y [#y]
let world gis:envelope-of paldrino
let miny item 2 world
let maxy item 3 world
report ((#y - miny) / (maxy - miny)) * (max-pycor - min-pycor) + min-pycor
end
In the end, the problem is that NetLogo doesn't perfectly align those two files: polygons (paldrino) and network (cities). Approximately it put them ok, but I need them to be perfectly set in the world. For example, some cities should have been in one polygon, but they are in the adjacent polygon.
So, for example, this is how NetLogo puts them:
And this is how they should be (read in QGIS):
If anyone please can help me or point me in another direction. I start losing my mind.
Thank you!

Related

Netlogo : Uploading a gis shapefile and preventing two polygons from overlapping

Good morning.
I upload a shapefile and ask patches with the centroid of each polygons to set some properties from the shapefile attributes.
gis:set-world-envelope (gis:envelope-of shpefile)
ask patches [set pcolor white]
gis:set-drawing-color black
gis:draw shapefile 0.5
;; ask patches gis:intersecting BE_WAL_Parcels_2015
;; [ set is-farm? true]
let n 1
foreach gis:feature-list-of BE_WAL_Parcels_2015 [
polygone ->
let center-point gis:location-of gis:centroid-of polygone
let x-coordinate item 0 center-point
let y-coordinate item 1 center-point
;; I need to add here the possibility to move the centroid of one px and py
ask patch x-coordinate y-coordinate [
ifelse (ID-parcel = 0) [
;; set an ID to the patch
set ID-temp n
set ID-parcel gis:property-value polygone "ID_PRCL"
set ID-farm gis:property-value polygone "ID_FARM"
[ set pcolor red
print x-coordinate]
]
set n n + 1
]
I added an ifelse condition to make sure that one polygons centroid is not overlapping a precedent computed polygon (set pcolor to red). I know that 1871 polygons are overlapping each other, see the a small part of the world:
I'd like to add the following action: if the patches is already defined with an id-parcel, then move to the closest one that is empty.
I'm now sure where to write that since the ifelse is inside a ask patch procedure...
Moreover, I've been playsing with the world size and patch size to minimize the risk of overlapping but the shapefile seems to adapt to the world size/patch size. Is there a way to increase the number of patches inside one polygon ? So make the patches smaller without decreasing the size of polygons
I attach here printscreen of a small part of the world as support
My second question is still OPEN (world and patch size) but I managed to find a way out (at least, it looks like OK) for my first question by sprouting a turtle on any patches that welcome a parcel from the shapefile, and afterwards checking whether there is already a turtle on the patche before assigning the next parcels. Here below is the few lines of codes. Any comment is obviously welcome ! :)
to setup-parcels
ca
reset-timer
resize-world 1500 * 0 ( 1500 * 1 ) ( 1500 * -1 ) 1500 * 0
gis:load-coordinate-system "BE_WAL_Parcels2006_Netlogo_selection_2.prj"
set BE_WAL_Parcels_2006 gis:load-dataset "BE_WAL_Parcels2006_Netlogo_selection_2.shp"
gis:set-world-envelope (gis:envelope-of BE_WAL_Parcels_2006)
ask patches [set pcolor white]
gis:set-drawing-color black
gis:draw BE_WAL_Parcels_2006 0.5
let n 1
foreach gis:feature-list-of BE_WAL_Parcels_2006 [
polygone ->
let center-point gis:location-of gis:centroid-of polygone
let x-coordinate item 0 center-point
let y-coordinate item 1 center-point
let occupied turtles with [xcor = x-coordinate AND ycor = y-coordinate]
ifelse any? occupied [
set x-coordinate (item 0 center-point + 1)
set y-coordinate (item 1 center-point + 1)
ask patch x-coordinate y-coordinate [
sprout 1
set ID-parcel gis:property-value polygone "ID_PRCL"
print ID-parcel
set ID-farm gis:property-value polygone "ID_FARM"
]
]
[
ask patch x-coordinate y-coordinate [
sprout 1
set ID-parcel gis:property-value polygone "ID_PRCL"
set ID-farm gis:property-value polygone "ID_FARM"
]
]
set n n + 1
]
clear-turtles
end

Small shift when transforming from GIS to netlogo coordinates

When storing turtle coordinates as GIS coordinates, and then loading them into NetLogo by converting them back to NetLogo coordinates, there is a slight shift in position.
This is the code I use to store NetLogo to GIS coordinates:
let env gis:envelope-of agentToStore
file-open "agentLocations.csv"
file-print (word first env "," last env)
file-close
And this is the code I use to convert GIS coordinates back to NetLogo coordinates (here x and y are coordinates read from the file):
let envelope gis:world-envelope
let xscale (max-pxcor - min-pxcor) / (item 1 envelope - item 0 envelope)
let yscale (max-pycor - min-pycor) / (item 3 envelope - item 2 envelope)
if x >= item 0 envelope and x <= item 1 envelope
and y >= item 2 envelope and y <= item 3 envelope[
let netlogo-x (x - item 0 envelope) * xscale + min-pxcor
let netlogo-y (y - item 2 envelope) * yscale + min-pycor
ask patch (ceiling netlogo-x) (floor netlogo-y) [sprout 1]
]
Without 'ceiling' and 'floor', the loaded agent is always shifted by a cell in NetLogo. However even with ceiling and floor, there is still a small shift by in GIS space for some agents, which affects my output. Is there a better way of doing this?

Updating parameters in a function being called by Octave's fsolve

I am working on modeling the motion of a single actuated leg in Octave. The leg has 3 points: a stationary hip (point A), a foot (point B) that moves along a known path, and a knee (point C) whose location and angle I am trying to solve for.
Using the code below I can successfully solve for the knee's XYZ position and relevant angles for a single value of the parameters s0 and Theta_H.
Now I want to be able to loop through multiple s0 and Theta_H values and run the solver. My problem is that I can't figure out how to pass new values for those variables into the equations function.
The reason this is tricky is that the function format necessary to use Octave's fsolve prevents entering inputs other than the unknowns into the function. I've tried updating a global variable as an indexer but to do that I would need to clear all workspace variables which causes other problems.
Any ideas on how to update the parameters in this function while still being able to input it into fsolve would be really appreciated!
The code below calls the solver:
global AC = 150; % length of the thigh limb
global CB = 150; % length of the shin limb
global lspan = 75; % width span of the foot touch down wrt the hip
global bob = 10; % height of the hip joint off the ground during a step
inits = [ .75; 2.35; 37; 0; 125]; % initial guesses at horizontal step position
% x(1): hip joint - guessing a 45 deg (.75 rad) angle for hip joint
% x(2): knee joint - guessing a 135 deg (2.35 rad) angle (wrt to vert)
% x(3): X position of the knee joint - guessing middle of the leg span in mm
% x(4): Y position of the knee joint - know it is 0 mm at the horizontal step position
% x(5): Z position of the knee joint - guessing the height to be ~80% of the height of a limb
[x, fval, info] = fsolve(#Rug_Bug_Leg, inits); % when running fsolve for the first time often have to remove the output suppress
The code below shows the function containing the system of equations to be solved by Octave's fsolve function:
function y = Rug_Bug_Leg(x)
global AC;
global CB;
global lspan;
global bob;
s0 = 0; % fore/aft (Y) position of the foot during the step. Trying to iterate this
Theta_H = 0; % hip angle during the step. Trying to iterate this
y = zeros(6,1); % zeros for left side of each equation
% First set of equations, Joint C wrt to Joint A
y(1) = -1*x(3)+AC*sin(x(1))*cos(Theta_H);
y(2) = -1*x(4)+AC*sin(x(1))*sin(Theta_H);
y(3) = -1*bob - x(5)+AC*cos(x(1));
% Second set of equations, Joint B wrt to Joint C
y(4) = x(3)-lspan +CB*sin(x(2))*cos(Theta_H);
y(5) = x(4) - s0 +sin(x(2))*sin(Theta_H);
y(6) = x(5) + bob + CB*cos(x(2));
end function
You can definitely do that!
All you need to do is create a function that returns a function.
First have your Rug_Bug_Leg function take s0 and Theta_H as inputs:
function y = Rug_Bug_Leg(x, s0, Theta_H)
% ...
endfunction
Then, you can write a "wrapper" function around Rug_Bug_Leg like this:
rbl = #(s0, Theta_H) #(x) Rug_Bug_Leg(x, s0, Theta_H)
Now, if you call rbl with some values (s0,Theta_H), it will return a function that takes x as input and returns Rug_Bug_Leg(x,s0,Theta_H).
For instance, rbl(0,0) returns the function:
#(x) Rug_Bug_Leg(x,0,0)
Here's a sample usage:
for s0=1:10
for Theta_H=1:10
[x, fval, info] = fsolve( rbl(s0,Theta_H), inits );
endfor
endfor

Mathematica plot is a straight line

So I'm trying to knock out this last problem, and I'm following my teacher's guide but my graph seems to still be off, the problem is:
Use the FindRoot command in Mathematica to define an inverse function g(y) to y = f(x) = 3x + tan(x) with the restriction ‑pi/2 < x < pi/2. Use x = tan-1(y) as a starting value. Then use the Plot command to make a graph of g(y).
This is how I wrote it out:
g[y_] := x /. FindRoot[3 x + Tan[x] == y, {x, ArcTan[y]}]
Plot[g[y], {y, (-Pi/2), (Pi/2)}]
I'm not sure exactly what the problem is, but it shows the graph as just being a straight line through the origin. I'm not sure if this is how it's supposed to be (which I assume it's not), but any and all help would be much appreciated!
Having your equation,
3 x + Tan[x] == y
You can check the correctness of the plot of g(y) by plotting y(x):
Plot[3 x + Tan[x], {x, -.4, .4}]
As you can easily see, it is a straight line through the origin. g(y) is inverse of y(x) by definition, so you can get a plot of g(y) it just by exchanging the y and x axes:
Plot[3 x + Tan[x], {x, -.4, .4},
PlotRange -> All] /. {x_Real, y_Real} :> {y, x}

Convert SVG Co-ordinates to HTML Image Map Co-ordinates

I followed https://stackoverflow.com/a/7669029/1223045 's instructions to automate the process of plotting co-ordinates on an image and was successful in generating the SVG co-ordinates for a area.
Now in order to use the same co-ordinates in area map, I will need to convert it to its equivalent format and this is where I'm struggling.
I came across a python script which does the conversion process, but since I have no idea about python, I don't know how to use it or how to proceed ahead with it.
Are there any other alternatives aside from the above script?
To translate svg coordinates must take each coordinate and move it to a total displacement figures , groups and all svg.
Sample code for translation in svg map area:
$ coord = "";
$ x = $ offset_x * $ scale_x + $ translate_x;
$ y = $ offset_y * $ scale_y + $ translate_y;
foreach ($ coordinates [ 1 ] as $ k => $ a) {
if ($ k% 2 == 0) {
$ coord. = round ($ x). ",";
$ x + = $ a * $ scale_x;
} else {
$ coord. = round ($ y). ",";
$ y + = $ a * $ scale_y;
}
}
$ coord = substr ($ coord, 0, -1) ;
Where translate x / y and scale x / y refer to g, and offset x / y coordinates of the starting offset figure.
In general then svg coordinates are written in the normal form , the main thing to take into account all the offsets and the fact that svg coordinates considered each of the previous one, but in all map area coordinates are taken from the origin.