Specifying location of agents that are generated within an agent that is placed on GIS map - anylogic

So in this model I have several hospital-agents that are placed randomly in an area. These hospitals contains a process flow and at some point in this process flow a new agent 'Bones' is generated, using a split block. The location of these Bones-agents is correctly specified by setting it equal to the (x,y) coordinates of the hospital.
Now I want to make the model more realistic by placing the hospitals in actual location in a GIS map. I did this with success. However, now I need to re-specify the location of the Bones-agents. At the moment of generating the first Bones-agent, I get the follow error:
root.Hospital1.splitblock:
Error when trying to initialize new agent
Caused by: root.Hospital2:
This agent is already defined as agent living in space 'Continuous, based on
GIS map' and can't have behaviour for space 'Continuous'This agent is already
defined as agent living in space 'Continuous, based on GIS map' and can't
have behaviour for space 'Continuous'
What do I need to do to make this work? I have tried setting the location of the Bones-agent equal to the longitude and latitude of the hospital agent with a function:
double longitude = getLongitude();
return longitude;
I did the same for het latitude. I then inputted these functions in the 'latitude' fields of the split block.

When you develop a model, you have to choose what kind of space you will use. Remember that all the canvas in which you put agents, and the map and stuff is based on a scale, so you can't mix a map with elements that are created with the space markup (with space markup i mean nodes, paths, rectangular nodes etc).
So the bones agents should also be placed in the map... It seems that you are not doing that, and you are probably placing the bones agent using the space markup.
But it's possible to do this of course, but you have to do it in another agent. Create a new agent called continuousSpace for instance, and place your bones agents there.
After that you will have to create a navigation button using viewAreas (from the presentation palette) to move from one agent to the other (meaning from the gis space to the markup space).
Otherwise, you can also place the bonesagents in the gis space (in the map) and it will also work.
Good luck :)

Related

Keeping agent in the same location when using gotoPopulation

I have a population of agents (containers) inside another agent (ship). This is required so that the containers will move with the ship. Once the ship docks, I want the containers to change from the population in 'ship' to the population in 'main' . When I use the following
gotoPopulation(main.containers_main);
to send a container agent to a population of containers in main, the container will move to 0,0 in the main environment.
The above code is placed in the container agent.
Is there a way to change an agent's population but keep it in the same location?
Thanks
I don't think so. As for agents, there is no "same position", they are always relative to something (previously relative to Ship, now to main).
But you can manually position them at the same (apparent) position by:
getting the container's relative position on main while still in Ship: getX() + ship.getX() (same for Y, assuming ship is embedded in Main and container in Ship) --> store briefly as double myPosX
move to new population on main as you do above
set "new" pos relative to Main: setX(myPosX)
It sounds cumbersome but makes sense, once you understand that embedded agent positions are always relative to their parent. Remove the parent and you need to account for adjusted the relative position to keep them in the (seemingly) "same" position

How to make pedestrians appear at AreaNode with attractors from a pedSource

I am working on an evacuation project for a floor and would like to create a distribution of pedestrians from the pedSource block. These pedestrians will already appear in an area when I run the simulation. I want to obtain a fixed number of pedestrians in one area while the rest is distributed to other areas.
I have made a collection of areas that pedestrians will appear using allLocations (area, area1, area2 and OfficeArea). The event is triggered by an event and using a delay block. The max amount of pedestrians at the given floor is 100
Image of block flowchart
Image of floor layout plan
This is the code I tried where pedestrians would appear in the areas:
allLocations.get(uniform_discr(0, allLocations.size()-1))
I expect a fixed 10 number of pedestrians in the office area and positioned where I set the attractors, but the actual result shows more than 10 number of pedestrians and do not appear at the set attractor.
Image of actual result
Setting an attractor as a target for pedestrians is according to the documentation only working for the blocks pedWait and pedGoTo (I could actually only get it to work with pedWait, not with pedGoTo). Therefore you cannot initialize agents directly onto attractors using the initial location or the jumpTo() function.
You have several options as a workaround:
Extract the x,y coordinates of the attractor, and use the type point(x,y) to define the initial location or the location for the jumpTo()
Instead of using (graphical) attractors consider just defining points by code directly
Use very small individual areas instead of one large area with attractors
Use a pedWait block in your process flow and let your pedestrians 'walk' to their initial positions. Give the model a short time until everybody is on the desired location before starting your evacuation. You can also run the model in super fast mode during this initial phase, so that it will barely be visible.

How to associate nested polygons to their parent from different GeoJSON files?

I have 3 separated GeoJSON files, each one contains a Feature Collection of Polygons.
First one for regions, the second for provinces and last for communes.
So the scenario is: for each region on click or zoom, show provinces in the clicked region then same thing with procinces.
I am using Leaflet for interactive map.
I am stuck on how to link every region with their provinces.
Is there any way to detect nested polygons?
Do I need a database or server side analysis?
Welcome to SO!
You would like to be able to tell the child ("nested") polygons of a given parent / container polygon, so that when a user clicks on the latter, you can show only the former.
The easiest would be to embed in your GeoJSON data properties some ID to each Feature, and for each child the ID of its container parent, and/or for each parent the array (list) of its children.
If your GeoJSON data does not already contain such association, then you could refactor it once to make it available. You have plenty ways of doing so, whether in GIS software, or directly using Client libraries. E.g. have a look at http://turfjs.org/ and its booleanContains method:
Boolean-contains returns True if the second geometry is completely contained by the first geometry. The interiors of both geometries must intersect and, the interior and boundary of the secondary (geometry b) must not intersect the exterior of the primary (geometry a).

Determining if Point is within an Enclosed Way in OSM

Given a GPS point, we want to check if it is within a parking area. Typically, parking areas in OSM have the amenity:parking key value pair and also are defined as a way that looks like a closed shape. If the search radius of the query has part of the shape boundary in it, then it will return the parking tags. But, if it is within the shape and not intersecting the boundary, then it doesn't return any tags. Is there a way to determine if that GPS point is within the shape to then return its tags?
We know there is a solution to load all parking lots within a certain area (e.g. a whole state or city) and then check if your GPS point is within any of them but this isn't ideal.

Framework for plotting latitude longitude in a map based on country, state and district depending on the zoom level

I need a framework which takes a set of latitude longitude points and plots on a world map, grouped by country having the count of points as a marker on each country. Grouping here is the count of latitude longitude points in a country.
And as I drill down into a country, the clustering should change to state based one. And the next level, to districts.
Leaflet marker cluster is something very similar to what I have asked for, but the grouping is based on proximity and it doesn't consider country or state boundaries. That is, they are not region aware.
Regionbound.com has tweaked in some code in the leaflet code for making it region aware,
Sample marker definition:
var marker1 = new L.marker([-37.8, 145], {regions: ["Asia-Pac", "Australia", "VIC", "Melbourne"]} );
But the sample code says, every latitude longitude must be defined along with some extra parameter containing place information.
I could get the place information using reverse geocoding, but reverse geocoding every latitude longitude is time consuming right.
Highmaps provided by Highcharts is one another solution, but there, every country has code which should be assigned a value[count of point coordinates belonging to that country].
But all I have is latitude longitude points, no country or state information.
Thus, I need something which takes only a set of latitude longitude and does clustering based on country, state, district depending on the zoom level.
You have 2 separate needs in your questions:
Map your lat/lng coordinates to appropriate administrative areas. E.g. through the reverse geocoding that you mention.
Display "clusters" on those administrative areas depending on zoom level.
As for point 1, you know that lat/lng points do not say by themselves which administrative area(s) they belong to. So "reverse geocoding every latitude longitude" is a mandatory step. Whether time consuming or not depends on the solution you choose to perform this operation.
If I understand correctly, you would like a "framework" that could do that automatically for you. But frameworks are usually data agnostic, and if they do not have data about boundaries of those administrative areas, they cannot help you.
You may rather look for "services" (like the Mapbox Geocoding API that you mention) or software that would already have such data. It is not time consuming if you can program the lookup (or perform "bulk" operations) and if you are not limited by the requests rate and your amount of points to map (which may be the case with Mapbox).
You could very well set up your own application to perform this mapping:
As for the dataset for administrative areas boundaries, you would probably be interested in links in this post: Are there any free administrative boundaries available as shapefiles? If your points are limited to a few countries, it will be easier for you to find the appropriate data source(s).
Once you have that data, many GIS software should be capable of mapping your lat/lng points to the areas they belong to. This would be mainly for a "one-shot" operation, if your set of points do not change much.
A "web-compatible" alternative would be for example to use Leaflet with point in polygon for Leaflet plugin. You would need your boundaries data converted to GeoJSON format first. Again, GIS software should be capable of doing so, or many online services as well (search for "convert geojson" for example).
A server-side solution would avoid having to manage the entire boundaries data through network and in client browser (if you need to perform the mapping dynamically). I am sure many GIS servers are capable of performing this operation, once they are fed with the boundaries data.
For point 2, once you have completed the above step, I think you would have many options available, including those you mention (RegionBound, Highmaps).
Even with standard mapping libraries (Leaflet, OpenLayers 3), you would just need to build your "clusters" (markers on administrative areas with a number saying how many points are in there), like you have to do with Highmaps anyway for example.
Computing the number of "clustered" point is as easy as filtering your points per area name / code. Then switch the clusters to the desired administrative level when the map zoom changes.
So the key is really to determine first to which areas your points belong to (point 1).
Then a small question would rise about where to place the "cluster" marker:
On centroid of the administrative area? You need the coordinates of that centroid from your data source, or a good algorithm to compute it from the boundaries (good luck on that…).
On "center" of the bounding box of the area? Leaflet can easily compute that: from your area vector shape, you would do myShape.getBounds().getCenter().
On barycentre / centroid of the clustered points? This is what Leaflet.markercluster and RegionBound do (do not know for Highmaps).
Good luck!