Moving an agent from one point to another point defined in a database - gis

I'm simulating the operation of a railroad.
I have a table with train departure time, departure location, and arrival location data. Locations are given using longitude and latitude coordinates.
I created my rail yards on the GIS map using their coordinates.
I can make the trains depart following the schedules in the table and the correct departure location.
But I can't get them to go to the right destination.
When trying to use the moveTo block you can only indicate a single destination. In my simulator, each train will go to a different yard.
How can I perform this movement using a data table and geographic coordinates?
Some pertinent remarks:
I'm not using the rail library. I'm working in the GIS space with routes determined by Anylogic itself. I didn't design or import railroads.
For this reason, I'm using the "source" and "moveTo" blocks from the process modeling library.
In the "moveTo" block I didn't find options that allow me to use the longitude and latitude data of the destination and which are stored in the data table (as I do in the "source" block).
Whenever I try to insert some code that does this, Anylogic returns saying the error:
"Exception during discrete event execution:
root:
Non-unique value in the database!"

It is better to rather use an agent-based approach for this kind of movement instead of doing it using move to blocks. It is hard to explain here but do some more tutorial examples and you will understand. You want the agents to move at a specific time and in a process flow modelling approach unless you use delay or hold blocks agents will flow from one block to the next as soon as there is space.
Here is an example of how to do it using the agent-based approach using your setup.
I have an agent called Trem with a dynamic event to move it to a specific location.
Now we populate the dynamic events with data from the database at the start of the model using the code below.
List<Tuple> rows = selectFrom(db_table)
.list();
for (Tuple row : rows) {
//What is the start time of the movement
double timeToTripBegin = dateToTime(row.get( db_table.trip_begin_time ));
//Lets create a new movement event to trigger the movement in the future
create_MoveToLocation(timeToTripBegin,
row.get( db_table.latitude_chegada ),
row.get( db_table.longitude_chegada ));
}
These events will then trigger the required movement for us when the event executes.

Related

Cesium CZML Model: is it possible to define multiple clock intervals?

In a Cesium CZML Model, I'd like to define multiple clocks, each one with its own time interval and multiplier, something like:
clock: {
interval: "2019-06-01T16:00:00Z/2019-06-01T16:10:00Z",
currentTime: "2019-06-01T16:00:00Z",
multiplier: 60,
range: "UNBOUNDED",
step: "SYSTEM_CLOCK_MULTIPLIER",
},
clock: {
interval: "2019-06-01T16:10:00Z/2019-06-01T16:20:00Z",
currentTime: "2019-06-01T16:10:00Z",
multiplier: 80,
range: "UNBOUNDED",
step: "SYSTEM_CLOCK_MULTIPLIER",
},
but this is not possible, because clock would be a duplicate key.
Is there a way to define consecutive time intervals, each one with its own clock multiplier?
Unfortunately I think the answer is "no", at least within a single CZML document. However, Cesium Viewer supports loading multiple DataSources at the same time, so you may load multiple CZML documents concurrently, and each will have its own clock settings.
Cesium.Viewer has a constructor option called automaticallyTrackDataSourceClocks that will cause it to update its own clock settings whenever a new dataSource (separate CZML file) is added, and when the active dataSource is removed. It also has a field, viewer.clockTrackedDataSource that is read/write, and can be used to set which dataSource is currently in charge of the viewer's clock settings.
But, you would need to write your own UI to show a list of available dataSources, and select which one controls the clock settings, if that's what's needed here. Cesium will not automatically jump from the end of one clock range to the start of the next, unless you write code to make this happen.
The viewer will always try to show objects from all dataSources that have "availability" during the current time range, even if the clock is tracking a range from another dataSource. When the time ranges overlap, users will see all objects from multiple dataSources together in the scene. When time ranges don't overlap, expired objects won't be shown, but some "permanent" objects such as stationary points may have infinite availability, and so continue to be shown outside of their parent dataSource's clock range. This can be controlled from within a CZML document by limiting such entities to have availability only within their own file's clock ranges.

Incorrect results using Autodesk Forge Viewer Geolocation Extension

This is related to my previous question. I'm posting a new question to try and explain the situation better.
I am placing marker objects on a model using data taken from drone surveys. I have access to high accuracy GPS data and also omega/phi/kappa rotation data.
I am trying to use the Autodesk.Geolocation extension to convert the lon/lat/alt data to viewer space.
All models were originally created in Revit.
When I use the Geolocation extension, it seems like the refPointLMV and GlobalOffset are not correctly being taken into account.
Here's an example:
As you can see, the selected point [0] on the model is nowhere near the real GPS coords. Also, the refPointLMV has huge values.
Something similar happens when I take some lon/lat/alt data from the drone photo. The drone GPS data will be close to the model positionLL84, e.g (4.586577106, 51.626037158, 49.095). However, when I do Geolocation.lonLatToLMV(4.586577106, 51.626037158, 49.095) I get a result way off screen.
We've had a support query open with Autodesk related to this open for over two months now, but not had much success there. They said the engineering team is too busy to work on this and recommended to try and fix the error on our side. Support ref LMV-5261.
I have been able to bring the result of Geolocation.lonLatToLMV into viewer space with the following code:
const gpsPosition = new THREE.Vector3(
longitude,
latitude,
altitude,
);
const position = viewer
.getExtension('Autodesk.Geolocation')
.lonLatToLmv(gpsPosition);
const data = viewer.model.getData();
const globalOffset = data.globalOffset;
const refPointTransform = data.refPointTransform;
// applying the transform
position.add(globalOffset)
position.applyMatrix4(refPointTransform);
// HACK: after applying the above transforms, a final
// rotation of -45 degrees is required to move the points into position
// once this has been done, the locations match up exactly to photos.
// Seems like a weird hack, but I've tested with over 20 drone photos, they all match up.
const quaterion = new THREE.Quaternion().setFromEuler(
new THREE.Euler(0, 0, -Math.PI / 4),
);
position.applyQuaternion(quaterion);
The problem here is that we are testing with a single model and this is clearly not a robust solution that we can expect to work with all future models and drone data we throw at it.
How long is it likely to take for the engineering team to fix this? Or are they likely to fix this at all?
Sorry for the delay due to the Chinese New Year. After checking with our engineering team, the current solution is to do the followings:
Move the Project base point to N0 E0, but remain the angle to true north
Copy the LAT LONG to Survey point
Afterward, the result of the GEO conversion should be expected.
Here are the snapshots of the above setting and the result

D3js json structure

I'm doing some charts with analytics regarding a game. Here is the basic assumptions.
There are three possible actions a player can make.
Player can attack
Player can deffend
Player can run ( in 2 directions forwards and backwards)
Each action can happen in one of the three battlegrounds (bg a, bg b, bg c)
A player can be human or alien. Each player regarding of race can have a level.
Each player executes a particular action at a particular time.
Now i need to chart these things.
Piechart of the players race
Piechart of where the actions took place(in which of the 3 battlegrounds)
A barchart of the players level
A line chart for attacks based on time
A line chart for defends based on time
A linechart for runs( oneline for each direction of running) based on time
Each chart needs to be connected to the other ones (kondof the crossfilter flight charts are) . So for example if i click on the piechart with the player race and chose human the other charts update accordingly to reflect levels, and battlegrounds and actions pertaining just to that race.
Bottom line is i am having a hard time structuring my json input. Can any experts give me some hints?
Thank you for your time.
As I see it, the most flexible way is to build up an array of "events" (an event can be anything a player might do) with timestamps. Something like:
var playerEvents = [
{ timestamp: 1352848500, player:'human', action:'attack', location:'bg A' },
{ timestamp: 1352848600, player:'alien', action:'run', meta:'dir=left', location:'bg B' },
....
]
Once you have that, any stats you want display would involve filtering this array of events down to whatever you need for the given graphic.

Using google maps API to find average speed at a location

I am trying to get the current traffic conditions at a particular location. The GTrafficOverlay object mentioned here only provides an overlay on an existing map.
Does anyone know how I can get this data from Google using their API?
It is only theorical, but there is perhaps a way to extract those data using the distancematrix api.
Method
1)
Make a topological road network, with node and edge, something like this:
Each edge will have four attributes: [EDGE_NUMBER;EDGE_SPEED;EDGE_TIME,EDGE_LENGTH]
You can use the openstreetmap data to create this network.
At the begining each edge will have the same road speed, for example 50km/h.
You need to use only the drivelink and delete the other edges. Take also into account that some roads are oneway.
2)
Randomly chose two nodes that are not closer than 5 or 10km
Use the dijsktra shortest path algorithm to calculate the shortest path between this two nodes (the cost = EDGE_TIME). Use your topological network to do that. The output will look like:
NODE = [NODE_23,NODE_44] PATH = [EDGE_3,EDGE_130,EDGE_49,EDGE_39]
Calculate the time needed to drive between the two nodes with the distance matrix api.
Preallocate a matrix A of size N X number_of_edge filled with zero value
Preallocate a matrix B of size 1 X number_of_edge filled with zero value
In the first row of matrix A fill each column (corresponding to each edge) with the length of the edge if the corresponding edge is in the path.
[col_1,col_2,col_3,...,col_39,...,col_49,...,col_130]
[0, 0, len_3,...,len_39,...,len_49,...,len_130] %row 1
In the first row of matrix B put the time calculated with the distance matrix api.
Then select two news node that were not used in the first path and repeat the operation until that there is no node left. (so you will fill the row 2, the row 3...)
Now you can solve the linear equation system: Ax = B where speed = 1/x
Assign the new calculated speed to each edge.
3)
Iterate the point 2) until your calculated speed start to converge.
Comment
I'm not sure that the calculated speed will converge, it will be interesting to test the method.I will try to do that if I got some time.
The distance matrix api don't provide a traveling time more precise than 1 minute, that's why the distance between the pair of node need to be at least 5 or 10 or more km.
Also this method fails to respect the Google's terms of service.
Google does not make available public API for this data.
Yahoo has a feed (example) with traffic conditions -- construction, accidents, and such. A write-up on how to access it is here.
If you want actual road speeds, you will probably need to work with a commercial provider.

Question about tracking user in a map application using cellid

I am trying to understand the concept of cellid (http://www.opencellid.org/api)
As per that, if we send a request
http://www.opencellid.org/cell/get?key=myapikey&mnc=1&mcc=2&lac=200&cellid=234
it will respond with the latitude and longitude.
I was wondering if this can be used from within a google map application for tracking a user or it needs to be used from within a mobile device?
If it can be used from within a web app, what parameters should it use for
mcc: mobile country code (decimal)
mnc: mobile network code (decimal)
lac: locale area code (decimal)
cellid: value of the cell id
E.g., will it work if we know the cell number of the person(e.g., 281 222 6700)
The request is just a lookup in the opencellid database.
It doesn't matter where the information is coming from.
If you know the MMC, MNC, LAC and CellID of a user/mobile device,
the request will return latitude and longitude if the cellID has been found in the DB.
There is no additional information transfered by using the request from within a J2ME app.
MCC+MNC+LAC+CELLID should be a unique identifier of a cell. (afaik those values can change over time,
but they still should be unique.)
More often than not, knowing just the LAC and CellID is sufficient.
However, you can't use this to track based on a number, only by cell tower parameters. Number tracking is a whole different ball game with VRL & HRL lookups which are hard to come by, very expensive ($100+ per lookup) and sometimes even illegal.
Google Maps also uses cell ID lookups to approximate the user's location before GPS kicks in (the translucent circle around a dot is actually data from Cell IDs).
That being said, opencellid has very minimal coverage and little or no updates to the project. Check out some paid players who offer wider coverages:
LocationAPI
Combian