mirror of
https://github.com/noncomputable/AgentMaps.git
synced 2026-01-18 16:27:05 +00:00
138 lines
9.2 KiB
HTML
138 lines
9.2 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>JSDoc: Tutorial: quickstart</title>
|
|
|
|
<script src="scripts/prettify/prettify.js"> </script>
|
|
<script src="scripts/prettify/lang-css.js"> </script>
|
|
<!--[if lt IE 9]>
|
|
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
|
|
<![endif]-->
|
|
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
|
|
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
|
|
</head>
|
|
|
|
<body>
|
|
|
|
<div id="main">
|
|
|
|
<h1 class="page-title">Tutorial: quickstart</h1>
|
|
|
|
<section>
|
|
|
|
<header>
|
|
|
|
|
|
<h2>quickstart</h2>
|
|
</header>
|
|
|
|
<article>
|
|
<p>Here we'll walk through building a simple AgentMaps simulation. I suggest looking at the detailed <a href="./">documentation</a> for
|
|
all of the AgentMaps functions and classes used here to get a better understanding of how they work.
|
|
If you're not so familiar with Leaflet, I suggest doing the same with the <a href="https://leafletjs.com/reference-1.3.2.html">Leaflet docs</a>.</p>
|
|
<p>You'll need AgentMaps, which you can get in a bundle <a href="https://unpkg.com/agentmaps@2/site/dist/agentmaps.js">here</a> or install via npm (<code>npm install agentmaps</code>). You'll also need the Leaflet script and style files, which you can get <a href="https://leafletjs.com/download.html">here</a>.</p>
|
|
<p>First, create an HTML document that:</p>
|
|
<ul>
|
|
<li>Loads the Leaflet.js style and script</li>
|
|
<li>Contains a <code><div></code> in which to embed the Leaflet map</li>
|
|
<li>Loads the AgentMaps script at the end</li>
|
|
</ul>
|
|
<pre class="prettyprint source lang-HTML"><code><!DOCTYPE HTML>
|
|
<html>
|
|
<head>
|
|
<link rel="stylesheet" href="leaflet_style.css">
|
|
<script src="leaflet_script.js"></script>
|
|
</head>
|
|
<body>
|
|
<div id="demo_map" style="height:400px"></div>
|
|
<script src="agentmaps.js"></script>
|
|
</body>
|
|
</html></code></pre><p>Assume we have the GeoJSON of a neighborhood stored in a variable like this, where the ellipses stand in for a list of map features (like streets):</p>
|
|
<pre class="prettyprint source lang-javascript"><code>let map_data = {
|
|
"type": "FeatureCollection",
|
|
"features": [
|
|
...
|
|
...
|
|
...
|
|
]
|
|
};</code></pre><p>You can use the sample data from the demos <a href="../resources/map_data.js">here</a>.</p>
|
|
<p>Have the top left and bottom right corners of a rectangle containing the neighborhood stored as an array of the corners' coordinates (i.e. [[lat, lon], [lat, lon]]):</p>
|
|
<pre class="prettyprint source lang-javascript"><code>let bounding_points = [[39.9058, -86.0910], [39.8992, -86.1017]]; </code></pre><p>Create a Leaflet map in the "demo_map" <code><div></code> of our HTML document:</p>
|
|
<pre class="prettyprint source lang-javascript"><code>let map = L.map("demo_map").fitBounds(bounding_points);</code></pre><p>The map will be empty, so tile it with OpenStreetMap's map tiles to see what's where:</p>
|
|
<pre class="prettyprint source lang-javascript"><code>L.tileLayer(
|
|
"http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
|
|
{
|
|
attribution: "Thanks to <a href=\"http://openstreetmap.org\">OpenStreetMap</a> community",
|
|
}
|
|
).addTo(map);</code></pre><p>Now that we have our map in place and the geographic data for our neighborhood in hand, create an Agentmap from the map:</p>
|
|
<pre class="prettyprint source lang-javascript"><code>let agentmap = L.A.agentmap(map);</code></pre><p>Now generate buildings and functional roads on the map based on the geographic data:</p>
|
|
<pre class="prettyprint source lang-javascript"><code>agentmap.buildingify(map_data, bounding_points);</code></pre><p>Now you can place agents on the map according to the rules of a custom agentFeatureMaker function. We'll use the built-in seqUnitAgentMaker,
|
|
which just assigns a number to each agent it generates in sequence, counting up from 0 to the number of agents you want, and places each agent
|
|
in the center of the unit with the same index as that number in the list of units. We'll make 50:</p>
|
|
<pre class="prettyprint source lang-javascript"><code>agentmap.agentify(50, agentmap.seqUnitAgentMaker);</code></pre><p>The simulation will start once we call <code>agentmap.run()</code>. The simulation is divided into consecutive "ticks", starting at tick 0.
|
|
On each tick, the following happens:</p>
|
|
<ul>
|
|
<li>The Agentmap runs its user-defined <code>Agentmap.controller()</code> (which we haven't defined yet)</li>
|
|
<li>Each agent runs its own user-defined <code>Agent.controller()</code> (we'll leave that empty)</li>
|
|
<li>Before and after each step an agent takes during the tick, it runs its own user-defined <code>Agent.fine_controller()</code> (we'll leave that empty too)</li>
|
|
</ul>
|
|
<p>The number of ticks elapsed at any point in the simulation is set in <code>agentmap.state.ticks</code>, functioning as a kind of clock.
|
|
We can call <code>agentmap.pause()</code> to stop the simulation, during which the ticks elapsed won't change, and then <code>agentmap.run()</code> to continue it.</p>
|
|
<p>So, let's define a controller function for our Agentmap:</p>
|
|
<pre class="prettyprint source lang-javascript"><code>agentmap.controller = function() {
|
|
|
|
};</code></pre><p>What do we want to happen on each tick? That is, what will we put in the controller function's body?
|
|
A simple simulation will involve the agents moving to a random unit every 300 ticks.</p>
|
|
<p>So first, we will have the <code>Agentmap.controller</code> check if the current number of ticks is a multiple of 300,
|
|
as we only want anything to happen every 300 ticks:</p>
|
|
<pre class="prettyprint source lang-javascript"><code>if (agentmap.state.ticks % 300 === 0) {
|
|
|
|
}</code></pre><p>Then, if number of ticks _is_ a multiple of 300, we want to tell each agent to do something,
|
|
so we will set up a loop that operates on each agent:</p>
|
|
<pre class="prettyprint source lang-javascript"><code>agentmap.agents.eachLayer(function(agent) {
|
|
|
|
}</code></pre><p>Now, for each agent, we'll generate a random number between 0 and the total number of units, and
|
|
store the unit whose index is that number, its ID, and the coordinates of its center:</p>
|
|
<pre class="prettyprint source lang-javascript"><code>let random_index = Math.floor(agentmap.units.count() * Math.random()),
|
|
random_unit = agentmap.units.getLayers()[random_index],
|
|
random_unit_id = agentmap.units.getLayerId(random_unit),
|
|
random_unit_center = random_unit.getBounds().getCenter();</code></pre><p>Then we will schedule for the agent a trip to that unit's center at approximately 1 meter per tick:</p>
|
|
<pre class="prettyprint source lang-javascript"><code>agent.scheduleTrip(random_unit_center, {type: "unit", id: random_unit_id}, 1, false, true);</code></pre><p>We want the agent to move along whatever path it has scheduled at each tick, so we will add the following to the end of our
|
|
controller function, outside of the 300 tick condition:</p>
|
|
<pre class="prettyprint source lang-javascript"><code>agent.moveIt();</code></pre><p>Altogether, our Agentmap's controller will look like this:</p>
|
|
<pre class="prettyprint source lang-javascript"><code>agentmap.controller = function() {
|
|
if (agentmap.state.ticks % 300 === 0) {
|
|
agentmap.agents.eachLayer(function(agent) {
|
|
let random_index = Math.floor(agentmap.units.count() * Math.random()),
|
|
random_unit = agentmap.units.getLayers()[random_index],
|
|
random_unit_id = agentmap.units.getLayerId(random_unit),
|
|
random_unit_center = random_unit.getBounds().getCenter();
|
|
|
|
agent.scheduleTrip(random_unit_center, {type: "unit", id: random_unit_id}, false, true);
|
|
}
|
|
}
|
|
|
|
agent.moveIt();
|
|
}</code></pre><p>Finally, now that we've got our Agentmap, buildings and agents loaded, and a controller defined, we can add:</p>
|
|
<pre class="prettyprint source lang-javascript"><code>agentmap.run();</code></pre><p>Once we load our HTML document, the simulation should begin and we can watch our agents move around the neighborhood.</p>
|
|
</article>
|
|
|
|
</section>
|
|
|
|
</div>
|
|
|
|
<nav>
|
|
<h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="Agent.html">Agent</a></li><li><a href="Agentmap.html">Agentmap</a></li></ul><h3>Tutorials</h3><ul><li><a href="tutorial-extra.html">extra</a></li><li><a href="tutorial-quickstart.html">quickstart</a></li></ul><h3>Global</h3><ul><li><a href="global.html#agent">agent</a></li><li><a href="global.html#agentmap">agentmap</a></li><li><a href="global.html#getIntersections">getIntersections</a></li><li><a href="global.html#isPointCoordinates">isPointCoordinates</a></li><li><a href="global.html#pointToCoordinateArray">pointToCoordinateArray</a></li><li><a href="global.html#reversedCoordinates">reversedCoordinates</a></li><li><a href="global.html#setupStreetFeatures">setupStreetFeatures</a></li><li><a href="global.html#setupUnitFeatures">setupUnitFeatures</a></li><li><a href="global.html#streetToGraph">streetToGraph</a></li></ul>
|
|
</nav>
|
|
|
|
<br class="clear">
|
|
|
|
<footer>
|
|
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Tue Sep 04 2018 11:46:34 GMT-0400 (Eastern Daylight Time)
|
|
</footer>
|
|
|
|
<script> prettyPrint(); </script>
|
|
<script src="scripts/linenumber.js"> </script>
|
|
</body>
|
|
</html> |