mirror of
https://github.com/noncomputable/AgentMaps.git
synced 2026-01-25 16:46:38 +00:00
Updates
This commit is contained in:
parent
e14040cc6a
commit
8f1ca23c2b
@ -20,7 +20,7 @@ let amap = L.A.agentmap(map);
|
||||
amap.buildingify(bounding_box, sample_data);
|
||||
|
||||
//Generate 100 agents according to the rules of seqUnitAgentMaker, displaying them as red, .5 meter radius circles.
|
||||
amap.agentify(1, amap.seqUnitAgentMaker, {radius: .5, color: "red", fillColor: "red"});
|
||||
amap.agentify(50, amap.seqUnitAgentMaker, {radius: .5, color: "red", fillColor: "red"});
|
||||
|
||||
//Do the following on each new tick.
|
||||
//amap.update_func = function() {
|
||||
|
||||
2
dist/agentmaps.js
vendored
2
dist/agentmaps.js
vendored
File diff suppressed because one or more lines are too long
867
docs/Agent.html
Normal file
867
docs/Agent.html
Normal file
@ -0,0 +1,867 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>JSDoc: Class: Agent</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">Class: Agent</h1>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<section>
|
||||
|
||||
<header>
|
||||
|
||||
<h2><span class="attribs"><span class="type-signature"></span></span>Agent<span class="signature">(latLng, options, agentmap)</span><span class="type-signature"></span></h2>
|
||||
|
||||
|
||||
</header>
|
||||
|
||||
<article>
|
||||
<div class="container-overview">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h4 class="name" id="Agent"><span class="type-signature"></span>new Agent<span class="signature">(latLng, options, agentmap)</span><span class="type-signature"></span></h4>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="description">
|
||||
Constructor for the Agent class, using Leaflet class system.
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h5>Parameters:</h5>
|
||||
|
||||
|
||||
<table class="params">
|
||||
<thead>
|
||||
<tr>
|
||||
|
||||
<th>Name</th>
|
||||
|
||||
|
||||
<th>Type</th>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<th class="last">Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
|
||||
|
||||
<tr>
|
||||
|
||||
<td class="name"><code>latLng</code></td>
|
||||
|
||||
|
||||
<td class="type">
|
||||
|
||||
|
||||
<span class="param-type">Array</span>
|
||||
|
||||
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<td class="description last">A pair of coordinates to place the agent at.</td>
|
||||
</tr>
|
||||
|
||||
|
||||
|
||||
<tr>
|
||||
|
||||
<td class="name"><code>options</code></td>
|
||||
|
||||
|
||||
<td class="type">
|
||||
|
||||
|
||||
<span class="param-type">Object</span>
|
||||
|
||||
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<td class="description last">An array of options for the agent, namely its layer.</td>
|
||||
</tr>
|
||||
|
||||
|
||||
|
||||
<tr>
|
||||
|
||||
<td class="name"><code>agentmap</code></td>
|
||||
|
||||
|
||||
<td class="type">
|
||||
|
||||
|
||||
<span class="param-type"><a href="Agentmap.html">Agentmap</a></span>
|
||||
|
||||
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<td class="description last">The agentmap instance in which the agent exists.</td>
|
||||
</tr>
|
||||
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h5 class="subsection-title">Properties:</h5>
|
||||
|
||||
|
||||
|
||||
<table class="props">
|
||||
<thead>
|
||||
<tr>
|
||||
|
||||
<th>Name</th>
|
||||
|
||||
|
||||
<th>Type</th>
|
||||
|
||||
|
||||
<th>Attributes</th>
|
||||
|
||||
|
||||
|
||||
|
||||
<th class="last">Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
|
||||
|
||||
<tr>
|
||||
|
||||
<td class="name"><code>feature.AgentMap_id</code></td>
|
||||
|
||||
|
||||
<td class="type">
|
||||
|
||||
|
||||
<span class="param-type">number</span>
|
||||
|
||||
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
<td class="attributes">
|
||||
|
||||
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
|
||||
|
||||
<td class="description last">The agent's instance id, so it can be accessed from inside the Leaflet layer. To avoid putting the actual instance inside the feature object.</td>
|
||||
</tr>
|
||||
|
||||
|
||||
|
||||
<tr>
|
||||
|
||||
<td class="name"><code>agentmap</code></td>
|
||||
|
||||
|
||||
<td class="type">
|
||||
|
||||
|
||||
<span class="param-type"><a href="Agentmap.html">Agentmap</a></span>
|
||||
|
||||
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
<td class="attributes">
|
||||
|
||||
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
|
||||
|
||||
<td class="description last">The agentmap instance in which the agent exists.</td>
|
||||
</tr>
|
||||
|
||||
|
||||
|
||||
<tr>
|
||||
|
||||
<td class="name"><code>place</code></td>
|
||||
|
||||
|
||||
<td class="type">
|
||||
|
||||
|
||||
<span class="param-type">Object.<string, number></span>
|
||||
|
||||
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
<td class="attributes">
|
||||
|
||||
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
|
||||
|
||||
<td class="description last">The id of the place (unit, street, etc.) where the agent is currently at.</td>
|
||||
</tr>
|
||||
|
||||
|
||||
|
||||
<tr>
|
||||
|
||||
<td class="name"><code>travel_state</code></td>
|
||||
|
||||
|
||||
<td class="type">
|
||||
|
||||
|
||||
<span class="param-type">Object</span>
|
||||
|
||||
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
<td class="attributes">
|
||||
|
||||
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
|
||||
|
||||
<td class="description last">Properties detailing information about the agent's trip that change sometimes, but needs to be accessed by future updates.
|
||||
<h6>Properties</h6>
|
||||
|
||||
<table class="props">
|
||||
<thead>
|
||||
<tr>
|
||||
|
||||
<th>Name</th>
|
||||
|
||||
|
||||
<th>Type</th>
|
||||
|
||||
|
||||
<th>Attributes</th>
|
||||
|
||||
|
||||
|
||||
|
||||
<th class="last">Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
|
||||
|
||||
<tr>
|
||||
|
||||
<td class="name"><code>traveling</code></td>
|
||||
|
||||
|
||||
<td class="type">
|
||||
|
||||
|
||||
<span class="param-type">boolean</span>
|
||||
|
||||
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
<td class="attributes">
|
||||
|
||||
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
|
||||
|
||||
<td class="description last">Whether the agent is currently on a trip.</td>
|
||||
</tr>
|
||||
|
||||
|
||||
|
||||
<tr>
|
||||
|
||||
<td class="name"><code>current_point</code></td>
|
||||
|
||||
|
||||
<td class="type">
|
||||
|
||||
|
||||
<span class="param-type"><a href="global.html#Point">Point</a></span>
|
||||
|
||||
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
<td class="attributes">
|
||||
|
||||
|
||||
|
||||
<nullable><br>
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
|
||||
|
||||
<td class="description last">The point where the agent is currently located.</td>
|
||||
</tr>
|
||||
|
||||
|
||||
|
||||
<tr>
|
||||
|
||||
<td class="name"><code>goal_point</code></td>
|
||||
|
||||
|
||||
<td class="type">
|
||||
|
||||
|
||||
<span class="param-type"><a href="global.html#Point">Point</a></span>
|
||||
|
||||
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
<td class="attributes">
|
||||
|
||||
|
||||
|
||||
<nullable><br>
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
|
||||
|
||||
<td class="description last">The point where the agent is traveling to.</td>
|
||||
</tr>
|
||||
|
||||
|
||||
|
||||
<tr>
|
||||
|
||||
<td class="name"><code>lat_dir</code></td>
|
||||
|
||||
|
||||
<td class="type">
|
||||
|
||||
|
||||
<span class="param-type">number</span>
|
||||
|
||||
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
<td class="attributes">
|
||||
|
||||
|
||||
|
||||
<nullable><br>
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
|
||||
|
||||
<td class="description last">The latitudinal direction. -1 if traveling to lower latitude (down), 1 if traveling to higher latitude (up).</td>
|
||||
</tr>
|
||||
|
||||
|
||||
|
||||
<tr>
|
||||
|
||||
<td class="name"><code>lng_dir</code></td>
|
||||
|
||||
|
||||
<td class="type">
|
||||
|
||||
|
||||
<span class="param-type">number</span>
|
||||
|
||||
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
<td class="attributes">
|
||||
|
||||
|
||||
|
||||
<nullable><br>
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
|
||||
|
||||
<td class="description last">The longitudinal direction. -1 if traveling to lesser longitude (left), 1 if traveling to greater longitude (right).</td>
|
||||
</tr>
|
||||
|
||||
|
||||
|
||||
<tr>
|
||||
|
||||
<td class="name"><code>slope</code></td>
|
||||
|
||||
|
||||
<td class="type">
|
||||
|
||||
|
||||
<span class="param-type">number</span>
|
||||
|
||||
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
<td class="attributes">
|
||||
|
||||
|
||||
|
||||
<nullable><br>
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
|
||||
|
||||
<td class="description last">The slope of the line segment formed by the two points between which the agent is traveling at this time during its trip.</td>
|
||||
</tr>
|
||||
|
||||
|
||||
|
||||
<tr>
|
||||
|
||||
<td class="name"><code>path</code></td>
|
||||
|
||||
|
||||
<td class="type">
|
||||
|
||||
|
||||
<span class="param-type">Array</span>
|
||||
|
||||
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
<td class="attributes">
|
||||
|
||||
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
|
||||
|
||||
<td class="description last">A sequence of LatLngs; the agent will move from one to the next, popping each one off after it arrives until the end of the street; or, until the travel_state is changed/reset.</td>
|
||||
</tr>
|
||||
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
|
||||
<tr>
|
||||
|
||||
<td class="name"><code>update_func</code></td>
|
||||
|
||||
|
||||
<td class="type">
|
||||
|
||||
|
||||
<span class="param-type">function</span>
|
||||
|
||||
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
<td class="attributes">
|
||||
|
||||
|
||||
|
||||
<nullable><br>
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
|
||||
|
||||
<td class="description last">Function to be called on each update.</td>
|
||||
</tr>
|
||||
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
|
||||
<dl class="details">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="agents.js.html">agents.js</a>, <a href="agents.js.html#line91">line 91</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</dl>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h3 class="subsection-title">Methods</h3>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h4 class="name" id=".setTravelToPlace"><span class="type-signature">(static) </span>setTravelToPlace<span class="signature">(goal_lat_lng, goal_place, replace_trip)</span><span class="type-signature"></span></h4>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="description">
|
||||
Set the agent up to travel directly from any point (e.g. of a street or unit) to a point (e.g. of another street or unit).
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h5>Parameters:</h5>
|
||||
|
||||
|
||||
<table class="params">
|
||||
<thead>
|
||||
<tr>
|
||||
|
||||
<th>Name</th>
|
||||
|
||||
|
||||
<th>Type</th>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<th class="last">Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
|
||||
|
||||
<tr>
|
||||
|
||||
<td class="name"><code>goal_lat_lng</code></td>
|
||||
|
||||
|
||||
<td class="type">
|
||||
|
||||
|
||||
<span class="param-type"><a href="global.html#LatLng">LatLng</a></span>
|
||||
|
||||
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<td class="description last">The point within the place to which the agent is to travel.</td>
|
||||
</tr>
|
||||
|
||||
|
||||
|
||||
<tr>
|
||||
|
||||
<td class="name"><code>goal_place</code></td>
|
||||
|
||||
|
||||
<td class="type">
|
||||
|
||||
|
||||
<span class="param-type">Object.<string, number></span>
|
||||
|
||||
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<td class="description last">The place to which the agent will travel. Must be of form {"unit": unit_id} or {"street": street_id}.</td>
|
||||
</tr>
|
||||
|
||||
|
||||
|
||||
<tr>
|
||||
|
||||
<td class="name"><code>replace_trip</code></td>
|
||||
|
||||
|
||||
<td class="type">
|
||||
|
||||
|
||||
<span class="param-type">Boolean</span>
|
||||
|
||||
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<td class="description last">Whether to empty the currently scheduled path and replace it with this new trip; false by default (the new trip is
|
||||
simply appended to the current scheduled path).</td>
|
||||
</tr>
|
||||
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<dl class="details">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="agents.js.html">agents.js</a>, <a href="agents.js.html#line219">line 219</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</dl>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</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>Global</h3><ul><li><a href="global.html#agentify">agentify</a></li><li><a href="global.html#agentmapFactory">agentmapFactory</a></li><li><a href="global.html#buildingify">buildingify</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#layerCount">layerCount</a></li><li><a href="global.html#pointToCoordinateArray">pointToCoordinateArray</a></li><li><a href="global.html#reversedCoordinates">reversedCoordinates</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 Jul 31 2018 17:04:58 GMT-0400 (Eastern Daylight Time)
|
||||
</footer>
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
<script src="scripts/linenumber.js"> </script>
|
||||
</body>
|
||||
</html>
|
||||
1669
docs/Agentmap.html
Normal file
1669
docs/Agentmap.html
Normal file
File diff suppressed because it is too large
Load Diff
5
docs/DOCS.md
Normal file
5
docs/DOCS.md
Normal file
@ -0,0 +1,5 @@
|
||||
# AgentMaps
|
||||
|
||||
DocsMake agent-based simulations on maps! Give it some neighborhood's OpenStreetMap data, and it'll generate buildings and give you utilities to embed and give rules to agents into the neighborhood.
|
||||
|
||||
After including and loading Leaflet, include this script to use Agentmaps: https://unpkg.com/agentmaps@1/dist/agentmaps.js.
|
||||
293
docs/agentmap.js.html
Normal file
293
docs/agentmap.js.html
Normal file
@ -0,0 +1,293 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>JSDoc: Source: agentmap.js</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">Source: agentmap.js</h1>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<section>
|
||||
<article>
|
||||
<pre class="prettyprint source linenums"><code>let lineSlice = require('@turf/line-slice').default,
|
||||
lineDistance = require('@turf/line-distance');
|
||||
|
||||
/**
|
||||
* The main class for building, storing, simulating, and manipulating agent-based models on Leaflet maps.
|
||||
*
|
||||
* @class Agentmap
|
||||
* @param {object} map - A Leaflet Map instance.
|
||||
* @property {object} map - A Leaflet Map instance.
|
||||
* @property {featureGroup} agents - A featureGroup containing all agents.
|
||||
* @property {featureGroup} units - A featureGroup containing all units.
|
||||
* @property {featureGroup} streets - A featureGroup containing all streets.
|
||||
* @property {object} state - Properties detailing the state of the simulation process.
|
||||
* @property {boolean} state.running - Whether the simulation is running or not.
|
||||
* @property {boolean} state.paused - Whether the simulation is paused.
|
||||
* @property {?number} state.animation_frame_id - The id of the agentmap's update function in the queue of functions to call for the coming animation frame.
|
||||
* @property {?number} state.time - The time elapsed since the start of the simulation.
|
||||
* @property {?number} state.ticks - The number of ticks elapsed since the start of the simulation.
|
||||
* @property {?number} state.prev_time - The time (time in seconds) when the last update was started.
|
||||
* @property {?number} state.time_start_delay - Ticks corresponding to the time of the last animation frame before the trip started. Subtracted from all subsequent time measurements so that the clock starts at 0, instead of whatever the actual time of that initial animation frame was.
|
||||
* @property {object} settings - Settings for the agentmap, filled with defaults.
|
||||
* @property {number} settings.movement_precision - On each interval of this many miliseconds between requestAnimationFrame calls, the agent's movements will be updated (for more precise movements than just updating on each call to requestAnimationFrame (60 fps max)).
|
||||
* @property {?function} update_func - Function to be called on each update.
|
||||
*/
|
||||
Agentmap = function (map) {
|
||||
this.map = map,
|
||||
this.units = null,
|
||||
this.streets = null,
|
||||
this.agents = null,
|
||||
this.pathfinder = null,
|
||||
this.state = {
|
||||
running: false,
|
||||
paused: false,
|
||||
animation_frame_id: null,
|
||||
time: null,
|
||||
ticks: null,
|
||||
prev_time: null,
|
||||
time_start_delay: null
|
||||
},
|
||||
this.settings = {
|
||||
movement_precision: .001
|
||||
},
|
||||
this.update_func = function() {};
|
||||
};
|
||||
|
||||
/**
|
||||
* Get an animation frame, have the agents update & get ready to be drawn, and keep doing that until paused or reset.
|
||||
*/
|
||||
Agentmap.prototype.run = function() {
|
||||
if (this.state.running === false) {
|
||||
this.state.running = true;
|
||||
|
||||
let animation_update = (function (rAF_time) {
|
||||
let total_time = rAF_time * .001;
|
||||
|
||||
if (this.state.paused === true) {
|
||||
this.state.paused = false,
|
||||
//The delay specifically due to the pause isn't the interval from the time at pause to the time at unpause,
|
||||
//but the interval from the time at pause (state.time, which already accounts for previous delays) to
|
||||
//the time at unpause the already accumulated delays; the unpause time alone is much higher without accounting
|
||||
//for previous delays and so the pause delay will look much bigger than it actually is if you subtracted previous delays.
|
||||
this.state.time_start_delay += (total_time - this.state.time_start_delay) - this.state.time;
|
||||
}
|
||||
|
||||
this.update(rAF_time);
|
||||
|
||||
this.state.animation_frame_id = L.Util.requestAnimFrame(animation_update);
|
||||
}).bind(this);
|
||||
|
||||
this.state.animation_frame_id = L.Util.requestAnimFrame(animation_update);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the simulation at the given time.
|
||||
* @private
|
||||
*
|
||||
* @param {number} rAF_time - Time passed by the browser's most recent animation frame.
|
||||
*/
|
||||
Agentmap.prototype.update = function(rAF_time) {
|
||||
let total_time = rAF_time * .001;
|
||||
this.state.ticks += 1;
|
||||
|
||||
if (this.state.time === null) {
|
||||
this.state.time = 0,
|
||||
this.state.prev_time = 0,
|
||||
this.state.ticks = 0;
|
||||
|
||||
//requestAnimationFrame doesn't start with timetamp 0; the first timetamp will typically be pretty large;
|
||||
//we want to store this initial timetamp and subtract it from each subsequent timetamp so that time
|
||||
//are counted from 0, not whatever timetamp the initial call to rAF happened to return.
|
||||
this.state.time_start_delay = total_time;
|
||||
}
|
||||
else {
|
||||
//See the comment immediately above.
|
||||
this.state.time = total_time - this.state.time_start_delay;
|
||||
}
|
||||
|
||||
//Execute user-provided per-tick instructions.
|
||||
this.update_func();
|
||||
|
||||
let movement_precision = this.settings.movement_precision,
|
||||
animation_time_interval = this.state.time - this.state.prev_time,
|
||||
steps_inbetween = Math.floor(animation_time_interval / movement_precision);
|
||||
|
||||
this.agents.eachLayer(function(agent) {
|
||||
agent.update(animation_time_interval, movement_precision, steps_inbetween);
|
||||
});
|
||||
|
||||
this.state.prev_time = this.state.time;
|
||||
};
|
||||
|
||||
/**
|
||||
* Stop the animation, reset the animation state properties, and delete the agents.
|
||||
*/
|
||||
Agentmap.prototype.reset = function() {
|
||||
L.Util.cancelAnimFrame(this.state.animation_frame_id);
|
||||
this.state.running = false,
|
||||
this.state.paused = false,
|
||||
this.state.animation_frame_id = null,
|
||||
this.state.time = null,
|
||||
this.state.ticks = null,
|
||||
this.state.prev_time = null,
|
||||
this.state.time_start_delay = null;
|
||||
|
||||
this.agents.clearLayers();
|
||||
};
|
||||
|
||||
/**
|
||||
* Stop the animation, stop updating the agents.
|
||||
*/
|
||||
Agentmap.prototype.pause = function() {
|
||||
L.Util.cancelAnimFrame(this.state.animation_frame_id);
|
||||
this.state.running = false,
|
||||
this.state.paused = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a point through which an agent can exit/enter a unit.
|
||||
*
|
||||
* @param {number} unit_id - The unique id of the unit whose door you want.
|
||||
* @returns {LatLng} - The coordinates of the center point of the segment of the unit parallel to the street.
|
||||
*/
|
||||
Agentmap.prototype.getUnitDoor = function(unit_id) {
|
||||
let unit = this.units.getLayer(unit_id);
|
||||
|
||||
if (typeof(unit) === "undefined") {
|
||||
throw new Error("No unit with the specified ID exists.");
|
||||
}
|
||||
|
||||
let unit_spec = unit.getLatLngs()[0],
|
||||
corner_a = unit_spec[0],
|
||||
corner_b = unit_spec[1],
|
||||
door = L.latLngBounds(corner_a, corner_b).getCenter();
|
||||
|
||||
return door;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the point on the adjacent street in front of the unit's door.
|
||||
*
|
||||
* @param {number} unit_id - The unique id of the unit whose door's corresponding point on the street you want.
|
||||
* @returns {LatLng} - The coordinates point of the adjacent street directly in front of unit's door.
|
||||
*/
|
||||
Agentmap.prototype.getStreetNearDoor = function(unit_id) {
|
||||
let unit = this.units.getLayer(unit_id);
|
||||
|
||||
if (typeof(unit) === "undefined") {
|
||||
throw new Error("No unit with the specified ID exists.");
|
||||
}
|
||||
|
||||
let unit_anchors = L.A.reversedCoordinates(unit.street_anchors),
|
||||
street_point = L.latLngBounds(...unit_anchors).getCenter();
|
||||
|
||||
return street_point;
|
||||
};
|
||||
|
||||
/**
|
||||
* Given a point on a street, find the nearest intersection on that street (with any other street).
|
||||
*
|
||||
* @param {LatLng} lat_lng - The coordinates of the point on the street to search from.
|
||||
* @param {Place} place - A place object corresponding to the street.
|
||||
* @returns {LatLng} - The coordinates of the nearest intersection.
|
||||
*/
|
||||
Agentmap.prototype.getNearestIntersection = function(lat_lng, place) {
|
||||
let street_id,
|
||||
street_feature;
|
||||
start_coords = L.A.pointToCoordinateArray(lat_lng);
|
||||
|
||||
if (place.street) {
|
||||
street_id = place.street;
|
||||
}
|
||||
else {
|
||||
throw new Error("place must be a street!");
|
||||
}
|
||||
|
||||
street_feature = this.streets.getLayer(street_id).toGeoJSON();
|
||||
|
||||
let intersections = this.streets.getLayer(street_id).intersections,
|
||||
intersection_points = [],
|
||||
intersection_distances = [];
|
||||
|
||||
for (let intersection in intersections) {
|
||||
for (let cross_point of intersections[intersection]) {
|
||||
let intersection_point = cross_point[0],
|
||||
intersection_coords = L.A.pointToCoordinateArray(intersection_point),
|
||||
segment = lineSlice(start_coords, intersection_coords, street_feature),
|
||||
distance = lineDistance(segment);
|
||||
|
||||
intersection_points.push(intersection_point);
|
||||
intersection_distances.push(distance);
|
||||
}
|
||||
}
|
||||
|
||||
let smallest_distance = Math.min(...intersection_distances),
|
||||
smallest_distance_index = intersection_distances.indexOf(smallest_distance),
|
||||
closest_intersection_point = L.latLng(intersection_points[smallest_distance_index]);
|
||||
|
||||
return closest_intersection_point;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an agentmap for the given map.
|
||||
*
|
||||
* @param {object} map - A Leaflet Map instance.
|
||||
* @returns {object} - An Agentmap instance.
|
||||
*/
|
||||
function agentmapFactory(map) {
|
||||
return new Agentmap(map);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of layers in a Leaflet layer group.
|
||||
*/
|
||||
function layerCount() {
|
||||
return this.getLayers().length;
|
||||
}
|
||||
|
||||
L.LayerGroup.include({count: layerCount});
|
||||
|
||||
exports.Agentmap = Agentmap,
|
||||
exports.agentmap = agentmapFactory;
|
||||
</code></pre>
|
||||
</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>Global</h3><ul><li><a href="global.html#agentify">agentify</a></li><li><a href="global.html#agentmapFactory">agentmapFactory</a></li><li><a href="global.html#buildingify">buildingify</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#layerCount">layerCount</a></li><li><a href="global.html#pointToCoordinateArray">pointToCoordinateArray</a></li><li><a href="global.html#reversedCoordinates">reversedCoordinates</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 Jul 31 2018 17:04:58 GMT-0400 (Eastern Daylight Time)
|
||||
</footer>
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
<script src="scripts/linenumber.js"> </script>
|
||||
</body>
|
||||
</html>
|
||||
516
docs/agents.js.html
Normal file
516
docs/agents.js.html
Normal file
@ -0,0 +1,516 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>JSDoc: Source: agents.js</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">Source: agents.js</h1>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<section>
|
||||
<article>
|
||||
<pre class="prettyprint source linenums"><code>let centroid = require('@turf/centroid').default,
|
||||
buffer = require('@turf/buffer').default,
|
||||
booleanPointInPolygon = require('@turf/boolean-point-in-polygon').default,
|
||||
along = require('@turf/along').default,
|
||||
nearestPointOnLine = require('@turf/nearest-point-on-line').default,
|
||||
lineSlice = require('@turf/line-slice').default,
|
||||
Agentmap = require('./agentmap').Agentmap,
|
||||
encodeLatLng = require('./routing').encodeLatLng;
|
||||
|
||||
/* Here we define agentify, the agent base class, and all other functions and definitions they rely on. */
|
||||
|
||||
/**
|
||||
* User-defined callback that gives a feature with appropriate geometry and properties to represent an agent.
|
||||
*
|
||||
* @callback agentFeatureMaker
|
||||
* @param {number} i - A number used to determine the agent's coordinates and other properties.
|
||||
* @returns {?Point} - Either a GeoJSON Point feature with properties and coordinates for agent i, including
|
||||
* a "place" property that will define the agent's initial agent.place; or null, which will cause agentify
|
||||
* to immediately stop its work & terminate.
|
||||
*/
|
||||
|
||||
/**
|
||||
* A standard featureMaker callback, which sets an agent's location as the center of a unit on the map.
|
||||
*
|
||||
* @memberof Agentmap
|
||||
* @type {agentFeatureMaker}
|
||||
*/
|
||||
function seqUnitAgentMaker(i){
|
||||
if (i > this.units.getLayers().length - 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let unit = this.units.getLayers()[i],
|
||||
unit_id = this.units.getLayerId(unit),
|
||||
center_point = centroid(unit.feature);
|
||||
center_point.properties.place = {"unit": unit_id},
|
||||
center_point.properties.layer_options = {radius: .5, color: "red", fillColor: "red"};
|
||||
|
||||
return center_point;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate some number of agents and place them on the map.
|
||||
*
|
||||
* @param {number} count - The desired number of agents.
|
||||
* @param {agentFeatureMaker} agentFeatureMaker - A callback that determines an agent i's feature properties and geometry (always a Point).
|
||||
*/
|
||||
function agentify(count, agentFeatureMaker) {
|
||||
let agentmap = this;
|
||||
|
||||
if (!(this.agents instanceof L.LayerGroup)) {
|
||||
this.agents = L.layerGroup().addTo(this.map);
|
||||
}
|
||||
|
||||
let agents_existing = agentmap.agents.getLayers().length;
|
||||
for (let i = agents_existing; i < agents_existing + count; i++) {
|
||||
//Callback function aren't automatically bound to the agentmap.
|
||||
let boundFeatureMaker = agentFeatureMaker.bind(agentmap),
|
||||
feature = boundFeatureMaker(i);
|
||||
if (feature === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
let coordinates = L.A.reversedCoordinates(feature.geometry.coordinates),
|
||||
place = feature.properties.place,
|
||||
layer_options = feature.properties.layer_options;
|
||||
|
||||
//Make sure the agent feature is valid and has everything we need.
|
||||
if (!L.A.isPointCoordinates(coordinates)) {
|
||||
throw new Error("Invalid feature returned from agentFeatureMaker: geometry.coordinates must be a 2-element array of numbers.");
|
||||
}
|
||||
else if (typeof(place.unit) !== "number" &&
|
||||
typeof(place.street) !== "number") {
|
||||
throw new Error("Invalid feature returned from agentFeatureMaker: properties.place must be a {unit: unit_id} or {street: street_id} with an existing layer's ID.");
|
||||
}
|
||||
|
||||
new_agent = agent(coordinates, layer_options, agentmap);
|
||||
new_agent.place = place;
|
||||
this.agents.addLayer(new_agent);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The main class representing individual agents, using Leaflet class system.
|
||||
* @private
|
||||
*
|
||||
* @class Agent
|
||||
*/
|
||||
let Agent = L.Layer.extend({});
|
||||
|
||||
/**
|
||||
* Constructor for the Agent class, using Leaflet class system.
|
||||
*
|
||||
* @name Agent
|
||||
* @constructor
|
||||
* @param {Array} latLng - A pair of coordinates to place the agent at.
|
||||
* @param {Object} options - An array of options for the agent, namely its layer.
|
||||
* @param {Agentmap} agentmap - The agentmap instance in which the agent exists.
|
||||
* @property {number} feature.AgentMap_id - The agent's instance id, so it can be accessed from inside the Leaflet layer. To avoid putting the actual instance inside the feature object.
|
||||
* @property {Agentmap} agentmap - The agentmap instance in which the agent exists.
|
||||
* @property {Object.<string, number>} place - The id of the place (unit, street, etc.) where the agent is currently at.
|
||||
* @property {Object} travel_state - Properties detailing information about the agent's trip that change sometimes, but needs to be accessed by future updates.
|
||||
* @property {boolean} travel_state.traveling - Whether the agent is currently on a trip.
|
||||
* @property {?Point} travel_state.current_point - The point where the agent is currently located.
|
||||
* @property {?Point} travel_state.goal_point - The point where the agent is traveling to.
|
||||
* @property {?number} travel_state.lat_dir - The latitudinal direction. -1 if traveling to lower latitude (down), 1 if traveling to higher latitude (up).
|
||||
* @property {?number} travel_state.lng_dir - The longitudinal direction. -1 if traveling to lesser longitude (left), 1 if traveling to greater longitude (right).
|
||||
* @property {?number} travel_state.slope - The slope of the line segment formed by the two points between which the agent is traveling at this time during its trip.
|
||||
* @property {Array} travel_state.path - A sequence of LatLngs; the agent will move from one to the next, popping each one off after it arrives until the end of the street; or, until the travel_state is changed/reset.
|
||||
* @property {?function} update_func - Function to be called on each update.
|
||||
*/
|
||||
Agent.initialize = function(latLng, options, agentmap) {
|
||||
this.agentmap = agentmap,
|
||||
this.place = null,
|
||||
this.travel_state = {
|
||||
traveling: false,
|
||||
current_point: null,
|
||||
goal_point: null,
|
||||
lat_dir: null,
|
||||
lng_dir: null,
|
||||
slope: null,
|
||||
path: [],
|
||||
};
|
||||
this.update_func = function() {};
|
||||
|
||||
L.CircleMarker.prototype.initialize.call(this, latLng, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop the agent from traveling, reset all the properties of its travel state.
|
||||
* @private
|
||||
*/
|
||||
Agent.resetTravelState = function() {
|
||||
for (let key in this.travel_state) {
|
||||
this.travel_state[key] =
|
||||
key === "traveling" ? false :
|
||||
key === "path" ? [] :
|
||||
null;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the agent up to travel to some point on the map.
|
||||
* @private
|
||||
*
|
||||
* @param {latLng} goal_point - The point to which the agent should travel.
|
||||
*/
|
||||
Agent.travelTo = function(goal_point) {
|
||||
let state = this.travel_state;
|
||||
state.traveling = true,
|
||||
state.current_point = this.getLatLng(),
|
||||
state.goal_point = L.latLng(goal_point),
|
||||
|
||||
//Negating so that neg result corresponds to the goal being rightward/above, pos result to it being leftward/below.
|
||||
state.lat_dir = Math.sign(- (state.current_point.lat - state.goal_point.lat)),
|
||||
state.lng_dir = Math.sign(- (state.current_point.lng - state.goal_point.lng)),
|
||||
|
||||
state.slope = Math.abs(((state.current_point.lat - state.goal_point.lat) / (state.current_point.lng - state.goal_point.lng)));
|
||||
};
|
||||
|
||||
/**
|
||||
* Start a trip along the path specified in the agent's travel_state.
|
||||
* @private
|
||||
*/
|
||||
Agent.startTrip = function() {
|
||||
if (this.travel_state.path.length > 0) {
|
||||
this.travelTo(this.travel_state.path[0]);
|
||||
}
|
||||
else {
|
||||
throw new Error("The travel state's path is empty! There's no path to take a trip along!");
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Given the agent's currently scheduled trips (its path), get the place from which a new trip should start (namely, the end of the current path).
|
||||
* That is: If there's already a path in queue, start the new path from the end of the existing one.
|
||||
* @private
|
||||
*/
|
||||
Agent.newTripStartPlace = function() {
|
||||
if (this.travel_state.path.length === 0) {
|
||||
start_place = this.place;
|
||||
}
|
||||
else {
|
||||
start_place = this.travel_state.path[this.travel_state.path.length - 1].new_place;
|
||||
}
|
||||
|
||||
return start_place;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the agent up to travel to a point within the unit he is in.
|
||||
* @private
|
||||
*
|
||||
* @param {LatLng} goal_lat_lng - LatLng coordinate object for a point in the same unit the agent is in.
|
||||
*/
|
||||
Agent.setTravelInUnit = function(goal_lat_lng, goal_place) {
|
||||
let goal_point = L.A.pointToCoordinateArray(goal_lat_lng),
|
||||
//Buffering so that points on the perimeter, like the door, are captured. Might be more
|
||||
//efficient to generate the door so that it's slightly inside the area.
|
||||
goal_polygon = buffer(this.agentmap.units.getLayer(goal_place.unit).toGeoJSON(), .001);
|
||||
|
||||
if (booleanPointInPolygon(goal_point, goal_polygon)) {
|
||||
goal_lat_lng.new_place = this.place;
|
||||
this.travel_state.path.push(goal_lat_lng);
|
||||
}
|
||||
else {
|
||||
throw new Error("The goal_lat_lng is not inside of the polygon of the goal_place!");
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the agent up to travel directly from any point (e.g. of a street or unit) to a point (e.g. of another street or unit).
|
||||
*
|
||||
* @param {LatLng} goal_lat_lng - The point within the place to which the agent is to travel.
|
||||
* @param {Object<string, number>} goal_place - The place to which the agent will travel. Must be of form {"unit": unit_id} or {"street": street_id}.
|
||||
* @param {Boolean} replace_trip - Whether to empty the currently scheduled path and replace it with this new trip; false by default (the new trip is
|
||||
* simply appended to the current scheduled path).
|
||||
*/
|
||||
Agent.setTravelToPlace = function(goal_lat_lng, goal_place, replace_trip = false) {
|
||||
let goal_layer = this.agentmap.units.getLayer(goal_place.unit) || this.agentmap.streets.getLayer(goal_place.street);
|
||||
|
||||
if (goal_layer) {
|
||||
let goal_coords = L.A.pointToCoordinateArray(goal_lat_lng);
|
||||
|
||||
//Buffering so that points on the perimeter, like the door, are captured. Might be more
|
||||
//efficient to generate the door so that it's slightly inside the area.
|
||||
let goal_polygon = buffer(goal_layer.toGeoJSON(), .001);
|
||||
|
||||
if (booleanPointInPolygon(goal_coords, goal_polygon)) {
|
||||
if (replace_trip === true) {
|
||||
this.travel_state.path.length = 0;
|
||||
}
|
||||
|
||||
let start_place = this.newTripStartPlace();
|
||||
|
||||
if (start_place.unit === goal_place.unit) {
|
||||
this.setTravelInUnit(goal_lat_lng, goal_place);
|
||||
return;
|
||||
}
|
||||
//Move to the street if it's starting at a unit and its goal is elsewhere.
|
||||
else if (typeof(start_place.unit) === "number") {
|
||||
let start_unit_door = this.agentmap.getUnitDoor(start_place.unit);
|
||||
start_unit_door.new_place = start_place;
|
||||
this.travel_state.path.push(start_unit_door);
|
||||
|
||||
let start_unit_street_id = this.agentmap.units.getLayer(start_place.unit).street_id,
|
||||
start_unit_street_point = this.agentmap.getStreetNearDoor(start_place.unit);
|
||||
start_unit_street_point.new_place = { street: start_unit_street_id };
|
||||
this.travel_state.path.push(start_unit_street_point);
|
||||
}
|
||||
|
||||
if (typeof(goal_place.unit) === "number") {
|
||||
let goal_street_point = this.agentmap.getStreetNearDoor(goal_place.unit),
|
||||
goal_street_point_place = { street: this.agentmap.units.getLayer(goal_place.unit).street_id };
|
||||
|
||||
//Move to the point on the street closest to the goal unit...
|
||||
this.setTravelAlongStreet(goal_street_point, goal_street_point_place);
|
||||
|
||||
//Move from that point into the unit.
|
||||
let goal_door = this.agentmap.getUnitDoor(goal_place.unit);
|
||||
goal_door.new_place = goal_place;
|
||||
this.travel_state.path.push(goal_door)
|
||||
this.setTravelInUnit(goal_lat_lng, goal_place);
|
||||
}
|
||||
else if (typeof(goal_place.street) === "number") {
|
||||
this.setTravelAlongStreet(goal_lat_lng, goal_place);
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new Error("The goal_lat_lng is not inside of the polygon of the goal_place!");
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new Error("No place exists matching the specified goal_place!");
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the agent up to travel to a point along the streets, via streets.
|
||||
* @private
|
||||
*
|
||||
* @param {LatLng} goal_lat_lng - The coordinates of a point on a street to which the agent should travel.
|
||||
* @param {Object<string, number>} goal_place - The place to which the agent will travel. Must be of form {"street": street_id}.
|
||||
*/
|
||||
Agent.setTravelAlongStreet = function(goal_lat_lng, goal_place) {
|
||||
let goal_coords,
|
||||
goal_street_id,
|
||||
goal_street_point,
|
||||
goal_street_feature,
|
||||
start_place = this.newTripStartPlace(),
|
||||
start_street_id,
|
||||
start_street_point,
|
||||
start_street_feature;
|
||||
|
||||
if (typeof(start_place.street) === "number" && typeof(goal_place.street) === "number") {
|
||||
start_street_id = start_place.street,
|
||||
start_street_point = this.travel_state.path[this.travel_state.path.length - 1];
|
||||
start_street_point.new_place = {street: start_street_id};
|
||||
|
||||
goal_street_id = goal_place.street,
|
||||
goal_street_feature = this.agentmap.streets.getLayer(goal_street_id).feature,
|
||||
goal_coords = L.A.pointToCoordinateArray(goal_lat_lng),
|
||||
goal_street_point = L.latLng(nearestPointOnLine(goal_street_feature, goal_coords).geometry.coordinates.reverse());
|
||||
goal_street_point.new_place = goal_place;
|
||||
}
|
||||
else {
|
||||
throw new Error("Both the start and end places must be streets!");
|
||||
}
|
||||
|
||||
if (start_street_id === goal_street_id) {
|
||||
this.setTravelOnSameStreet(start_street_point, goal_street_point, goal_street_feature, goal_street_id);
|
||||
}
|
||||
//If the start and end points are on different streets, move from the start to its nearest intersection, then from there
|
||||
//to the intersection nearest to the end, and finally to the end.
|
||||
else {
|
||||
let start_nearest_intersection = this.agentmap.getNearestIntersection(start_street_point, start_place),
|
||||
goal_nearest_intersection = this.agentmap.getNearestIntersection(goal_street_point, goal_place);
|
||||
|
||||
start_street_feature = this.agentmap.streets.getLayer(start_street_id).feature;
|
||||
|
||||
this.setTravelOnStreetNetwork(start_street_point, goal_street_point, start_nearest_intersection, goal_nearest_intersection);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the agent up to travel between two points on the same street.
|
||||
* @private
|
||||
*
|
||||
* @param start_lat_lng {LatLng} - The coordinates of the point on the street from which the agent will be traveling.
|
||||
* @param goal_lat_lng {LatLng} - The coordinates of the point on the street to which the agent should travel.
|
||||
* @param street_feature {Feature} - A GeoJSON object representing an OpenStreetMap street.
|
||||
* @param street_id {number} - The ID of the street in the streets layerGroup.
|
||||
*/
|
||||
Agent.setTravelOnSameStreet = function(start_lat_lng, goal_lat_lng, street_feature, street_id) {
|
||||
//lineSlice, regardless of the specified starting point, will give a segment with the same coordinate order
|
||||
//as the original lineString array. So, if the goal point comes earlier in the array (e.g. it's on the far left),
|
||||
//it'll end up being the first point in the path, instead of the last, and the agent will move to it directly,
|
||||
//ignoring the street, and then travel along the street from the goal point to its original point (backwards).
|
||||
//To fix this, I'm reversing the order of the coordinates in the segment if the last point in the line is closer
|
||||
//to the agent's starting point than the first point on the line (implying it's a situation of the kind described above).
|
||||
|
||||
let start_coords = L.A.pointToCoordinateArray(start_lat_lng),
|
||||
goal_coords = L.A.pointToCoordinateArray(goal_lat_lng),
|
||||
street_path_unordered = L.A.reversedCoordinates(lineSlice(start_coords, goal_coords, street_feature).geometry.coordinates);
|
||||
let start_to_path_beginning = start_lat_lng.distanceTo(L.latLng(street_path_unordered[0])),
|
||||
start_to_path_end = start_lat_lng.distanceTo(L.latLng(street_path_unordered[street_path_unordered.length - 1]));
|
||||
let street_path = start_to_path_beginning < start_to_path_end ? street_path_unordered : street_path_unordered.reverse();
|
||||
let street_path_lat_lngs = street_path.map(coords => L.latLng(coords));
|
||||
street_path_lat_lngs[0].new_place = { street: street_id },
|
||||
this.travel_state.path.push(...street_path_lat_lngs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the agent up to travel between two points on a street network.
|
||||
* @private
|
||||
*
|
||||
* @param start_lat_lng {LatLng} - The coordinates of the point on the street from which the agent will be traveling.
|
||||
* @param goal_lat_lng {LatLng} - The coordinates of the point on the street to which the agent should travel.
|
||||
* @param start_int_lat_lng {LatLng} - The coordinates of the nearest intersection on the same street at the start_lat_lng.
|
||||
* @param goal_int_lat_lng {LatLng} - The coordinates of the nearest intersection on the same street as the goal_lat_lng.
|
||||
*/
|
||||
Agent.setTravelOnStreetNetwork = function(start_lat_lng, goal_lat_lng, start_int_lat_lng, goal_int_lat_lng) {
|
||||
let path = this.agentmap.getPath(start_int_lat_lng, goal_int_lat_lng, start_lat_lng, goal_lat_lng, true);
|
||||
|
||||
for (let i = 0; i <= path.length - 2; i++) {
|
||||
let current_street_id = path[i].new_place.street,
|
||||
current_street_feature = this.agentmap.streets.getLayer(current_street_id).feature;
|
||||
|
||||
this.setTravelOnSameStreet(path[i], path[i + 1], current_street_feature, current_street_id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Continue to move the agent directly from one point to another, without regard for streets,
|
||||
* according to the time that has passed since the last movement. Also simulate intermediary movements
|
||||
* during the interval between the current call and the last call to moveDirectly, by splitting that interval
|
||||
* up with some precision (agentmap.settings.movement_precision) into some number of parts (steps_inbetween)
|
||||
* and moving slightly for each of them, for more precise collision detection than just doing it after each
|
||||
* call to moveDirectly from requestAnimationFrame (max, 60 times per second) would allow. Limiting movements to
|
||||
* each requestAnimationFrame call was causing each agent to skip too far ahead at each call, causing moveDirectly
|
||||
* to not be able to catch when the agent is within 1 meter of the goal_point... splitting the interval since the last
|
||||
* call up and making intermediary calls fixes that.
|
||||
* @private
|
||||
*
|
||||
* @param {number} rAF_time - The time when the browser's most recent animation frame was released.
|
||||
*/
|
||||
Agent.moveDirectly = function(animation_interval, intermediary_interval, steps_inbetween) {
|
||||
let state = this.travel_state;
|
||||
|
||||
//Fraction of the number of ticks since the last call to move the agent forward by.
|
||||
//Only magnitudes smaller than hundredths will be added to the lat/lng at a time, so that it doesn't leap ahead too far;
|
||||
//as the tick_interval is usually < 1, and the magnitude will be the leap_fraction multiplied by the tick_interval.
|
||||
const leap_fraction = .0001;
|
||||
|
||||
let move = (function(tick_interval) {
|
||||
if (state.goal_point.distanceTo(state.current_point) < 1) {
|
||||
if (typeof(state.path[0].new_place) === "object") {
|
||||
this.place = state.path[0].new_place;
|
||||
}
|
||||
|
||||
state.path.shift();
|
||||
|
||||
if (state.path.length === 0) {
|
||||
this.resetTravelState();
|
||||
return;
|
||||
}
|
||||
else {
|
||||
this.travelTo(state.path[0]);
|
||||
}
|
||||
}
|
||||
|
||||
let lat_change = state.lat_dir * state.slope * (leap_fraction * tick_interval),
|
||||
lng_change = state.lng_dir * (leap_fraction * tick_interval),
|
||||
new_lat_lng = L.latLng([state.current_point.lat + lat_change, state.current_point.lng + lng_change]);
|
||||
this.setLatLng(new_lat_lng);
|
||||
state.current_point = new_lat_lng;
|
||||
}).bind(this);
|
||||
|
||||
//Intermediary movements.
|
||||
for (let i = 0; i < steps_inbetween; ++i) {
|
||||
move(intermediary_interval);
|
||||
|
||||
if (state.traveling === false) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//Latest requested movement.
|
||||
if (state.traveling === true) {
|
||||
latest_interval = animation_interval - (this.agentmap.settings.movement_precision * steps_inbetween);
|
||||
move(latest_interval);
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Make the agent proceed with whatever it's doing and update its properties before the browser draws the next frame.
|
||||
* @private
|
||||
*
|
||||
* @param {number} rAF_time - The time when the browser's most recent animation frame was released.
|
||||
*/
|
||||
Agent.update = function(animation_interval, intermediary_interval, steps_inbetween) {
|
||||
this.update_func();
|
||||
|
||||
if (this.travel_state.traveling) {
|
||||
this.moveDirectly(animation_interval, intermediary_interval, steps_inbetween);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an agent object.
|
||||
*
|
||||
* @memberof Agentmap
|
||||
*/
|
||||
function agent(feature, options, agentmap) {
|
||||
return new L.A.Agent(feature, options, agentmap);
|
||||
}
|
||||
|
||||
Agentmap.prototype.agentify = agentify,
|
||||
Agentmap.prototype.seqUnitAgentMaker = seqUnitAgentMaker;
|
||||
|
||||
exports.Agent = L.CircleMarker.extend(Agent),
|
||||
exports.agent = agent;
|
||||
</code></pre>
|
||||
</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>Global</h3><ul><li><a href="global.html#agentify">agentify</a></li><li><a href="global.html#agentmapFactory">agentmapFactory</a></li><li><a href="global.html#buildingify">buildingify</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#layerCount">layerCount</a></li><li><a href="global.html#pointToCoordinateArray">pointToCoordinateArray</a></li><li><a href="global.html#reversedCoordinates">reversedCoordinates</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 Jul 31 2018 17:04:58 GMT-0400 (Eastern Daylight Time)
|
||||
</footer>
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
<script src="scripts/linenumber.js"> </script>
|
||||
</body>
|
||||
</html>
|
||||
400
docs/buildings.js.html
Normal file
400
docs/buildings.js.html
Normal file
@ -0,0 +1,400 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>JSDoc: Source: buildings.js</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">Source: buildings.js</h1>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<section>
|
||||
<article>
|
||||
<pre class="prettyprint source linenums"><code>let bearing = require('@turf/bearing').default,
|
||||
destination = require('@turf/destination').default,
|
||||
along = require('@turf/along').default,
|
||||
lineIntersect = require('@turf/line-intersect').default,
|
||||
intersect = require('@turf/intersect').default,
|
||||
Agentmap = require('./agentmap').Agentmap,
|
||||
streetsToGraph = require('./routing').streetsToGraph,
|
||||
getPathFinder = require('./routing').getPathFinder;
|
||||
|
||||
/* Here we define buildingify and all other functions and definitions it relies on. */
|
||||
|
||||
/**
|
||||
* Generate and setup the desired map features (e.g. streets, houses).
|
||||
*
|
||||
* @param {Array.<Array.<number>>} bounding_box - The map's top-left and bottom-right coordinates.
|
||||
* @param {object} OSM_data - A GeoJSON Feature Collection object containing the OSM features inside the bounding box.
|
||||
* @param {string} OSM_data_URL - URL from which to download equivalent OSM_data.
|
||||
*/
|
||||
function buildingify(bounding_box, OSM_data, OSM_data_URL) {
|
||||
//if (!GeoJSON_data && GeoJSON_data_URL) {}
|
||||
|
||||
let street_features = getStreetFeatures(OSM_data);
|
||||
|
||||
let street_options = {
|
||||
style: {
|
||||
"color": "yellow",
|
||||
"weight": 4,
|
||||
"opacity": .5
|
||||
},
|
||||
};
|
||||
|
||||
let street_feature_collection = {
|
||||
type: "FeatureCollection",
|
||||
features: street_features
|
||||
};
|
||||
|
||||
this.streets = L.geoJSON(
|
||||
street_feature_collection,
|
||||
street_options
|
||||
).addTo(this.map);
|
||||
|
||||
//Having added the streets as layers to the map, do any processing that requires access to those layers.
|
||||
this.streets.eachLayer(function(street) {
|
||||
let street_id = street._leaflet_id;
|
||||
|
||||
addStreetLayerIntersections.call(this, street, street_id);
|
||||
}, this);
|
||||
|
||||
this.streets.graph = streetsToGraph(this.streets),
|
||||
this.pathfinder = getPathFinder(this.streets.graph);
|
||||
|
||||
/**
|
||||
* Gets the intersections of all the streets on the map and adds them as properties to the street layers.
|
||||
*/
|
||||
function addStreetLayerIntersections(street, street_id) {
|
||||
street.intersections = typeof(street.intersections) === "undefined" ? {} : street.intersections;
|
||||
|
||||
this.streets.eachLayer(function(other_street) {
|
||||
let other_street_id = other_street._leaflet_id;
|
||||
|
||||
//Skip if both streets are the same, or if the street already has its intersections with the other street.
|
||||
if (typeof(street.intersections[other_street_id]) === "undefined" && street_id !== other_street_id) {
|
||||
let street_coords = street.getLatLngs().map(L.A.pointToCoordinateArray),
|
||||
other_street_coords = other_street.getLatLngs().map(L.A.pointToCoordinateArray),
|
||||
identified_intersections = L.A.getIntersections(street_coords, other_street_coords, [street_id, other_street_id]).map(
|
||||
identified_intersection =>
|
||||
[L.A.reversedCoordinates(identified_intersection[0]), identified_intersection[1]]
|
||||
);
|
||||
|
||||
if (identified_intersections.length > 0) {
|
||||
street.intersections[other_street_id] = identified_intersections,
|
||||
other_street.intersections = typeof(other_street.intersections) === "undefined" ? {} : other_street.intersections,
|
||||
other_street.intersections[street_id] = identified_intersections;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//Bind getUnitFeatures to "this" so it can access the agentmap as "this.agentmap".
|
||||
let unit_features = getUnitFeatures.bind(this)(OSM_data, bounding_box);
|
||||
|
||||
let unit_options = {
|
||||
style: {
|
||||
"color": "green",
|
||||
"weight": 1,
|
||||
"opacity": .87
|
||||
},
|
||||
};
|
||||
|
||||
let unit_feature_collection = {
|
||||
type: "FeatureCollection",
|
||||
features: unit_features
|
||||
};
|
||||
|
||||
this.units = L.geoJSON(
|
||||
unit_feature_collection,
|
||||
unit_options
|
||||
).addTo(this.map);
|
||||
|
||||
//Having added the units as layers to the map, do any processing that requires access to those layers.
|
||||
this.units.eachLayer(function(unit) {
|
||||
unit.street_id = unit.feature.properties.street_id,
|
||||
unit.street_anchors = unit.feature.properties.street_anchors,
|
||||
//Change the ID's in each unit's neighbours array into the appropriate Leaflet ID's.
|
||||
unit.neighbors = unit.feature.properties.neighbors.map(function(neighbor) {
|
||||
if (neighbor !== null) {
|
||||
let neighbor_id;
|
||||
this.units.eachLayer(function(neighbor_layer) {
|
||||
if (neighbor_layer.feature.properties.id === neighbor.properties.id) {
|
||||
neighbor_id = this.units.getLayerId(neighbor_layer);
|
||||
}
|
||||
}, this);
|
||||
|
||||
return neighbor_id;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}, this);
|
||||
}, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all appropriate units within the desired bounding box.
|
||||
* @private
|
||||
*
|
||||
* @param {Object} OSM_data - A GeoJSON Feature Collection object containing the OSM features inside the bounding box.
|
||||
* @returns {Array<Feature>} - array of features representing real estate units.
|
||||
*/
|
||||
function getUnitFeatures(OSM_data, bounding_box) {
|
||||
let proposed_unit_features = [];
|
||||
|
||||
this.streets.eachLayer(function(layer) {
|
||||
let street_feature = layer.feature,
|
||||
street_id = layer._leaflet_id,
|
||||
proposed_anchors = getUnitAnchors(street_feature, bounding_box),
|
||||
new_proposed_unit_features = generateUnitFeatures(proposed_anchors, proposed_unit_features, street_id);
|
||||
proposed_unit_features.push(...new_proposed_unit_features);
|
||||
});
|
||||
|
||||
unit_features = unitsOutOfStreets(proposed_unit_features, this.streets);
|
||||
|
||||
return unit_features;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all streets from the GeoJSON data.
|
||||
* @private
|
||||
*
|
||||
* @param {Object} OSM_data - A GeoJSON Feature Collection object containing the OSM streets inside the bounding box.
|
||||
* @returns {Array<Feature>} - array of street features.
|
||||
*/
|
||||
function getStreetFeatures(OSM_data) {
|
||||
let street_features = [];
|
||||
|
||||
for (let i = 0; i < OSM_data.features.length; ++i) {
|
||||
let feature = OSM_data.features[i];
|
||||
|
||||
if (feature.geometry.type === "LineString" && feature.properties.highway) {
|
||||
let street_feature = feature;
|
||||
|
||||
street_features.push(street_feature);
|
||||
}
|
||||
}
|
||||
|
||||
return street_features;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given two anchors, find four nearby points on either side
|
||||
* of the street appropriate to build a unit(s) on.
|
||||
* @private
|
||||
*
|
||||
* @param {Array<Array<Feature>>} unit_anchors - array of pairs of points around which to anchor units along a street.
|
||||
* @param {Array<Feature>} proposed_unit_features - array of features representing real estate units already proposed for construction.
|
||||
* @param {string} street_feature_id - The Leaflet layer ID of the street feature along which the unit is being constructed..
|
||||
* @returns {Array<Feature>} unit_features - array of features representing real estate units.
|
||||
*/
|
||||
function generateUnitFeatures(unit_anchors, proposed_unit_features, street_feature_id) {
|
||||
//One sub-array of unit features for each side of the road.
|
||||
let unit_features = [[],[]],
|
||||
starting_id = proposed_unit_features.length,
|
||||
increment = 1;
|
||||
|
||||
for (let anchor_pair of unit_anchors) {
|
||||
//Pair of unit_features opposite each other on a street.
|
||||
let unit_pair = [null, null];
|
||||
|
||||
for (let i of [1, -1]) {
|
||||
let anchor_a = anchor_pair[0].geometry.coordinates,
|
||||
anchor_b = anchor_pair[1].geometry.coordinates,
|
||||
anchor_latLng_pair = [anchor_a, anchor_b],
|
||||
street_buffer = 6 / 1000, //Distance between center of street and start of unit.
|
||||
house_depth = 18 / 1000,
|
||||
angle = bearing(anchor_a, anchor_b),
|
||||
new_angle = angle <= 90 ? angle + i * 90 : angle - i * 90, //Angle of line perpendicular to the anchor segment.
|
||||
unit_feature = {
|
||||
type: "Feature",
|
||||
properties: {
|
||||
street: "none"
|
||||
},
|
||||
geometry: {
|
||||
type: "Polygon",
|
||||
coordinates: [[]]
|
||||
}
|
||||
};
|
||||
unit_feature.geometry.coordinates[0][0] = destination(anchor_a, street_buffer, new_angle).geometry.coordinates,
|
||||
unit_feature.geometry.coordinates[0][1] = destination(anchor_b, street_buffer, new_angle).geometry.coordinates,
|
||||
unit_feature.geometry.coordinates[0][2] = destination(anchor_b, street_buffer + house_depth, new_angle).geometry.coordinates,
|
||||
unit_feature.geometry.coordinates[0][3] = destination(anchor_a, street_buffer + house_depth, new_angle).geometry.coordinates;
|
||||
unit_feature.geometry.coordinates[0][4] = unit_feature.geometry.coordinates[0][0];
|
||||
|
||||
//Exclude the unit if it overlaps with any of the other proposed units.
|
||||
let all_proposed_unit_features = unit_features.concat(...proposed_unit_features);
|
||||
if (noOverlaps(unit_feature, all_proposed_unit_features)) {
|
||||
//Recode index so that it's useful here.
|
||||
if (i === 1) {
|
||||
i = 0;
|
||||
}
|
||||
else {
|
||||
i = 1;
|
||||
}
|
||||
|
||||
unit_feature.properties.street_id = street_feature_id,
|
||||
unit_feature.properties.street_anchors = anchor_latLng_pair,
|
||||
unit_feature.properties.neighbors = [null, null, null],
|
||||
unit_feature.properties.id = starting_id + increment,
|
||||
increment += 1;
|
||||
|
||||
if (unit_features[i].length !== 0) {
|
||||
//Make previous unit_feature this unit_feature's first neighbor.
|
||||
unit_feature.properties.neighbors[0] = unit_features[i][unit_features[i].length - 1],
|
||||
//Make this unit_feature the previous unit_feature's second neighbor.
|
||||
unit_features[i][unit_features[i].length - 1].properties.neighbors[1] = unit_feature;
|
||||
}
|
||||
|
||||
if (i === 0) {
|
||||
unit_pair[0] = unit_feature;
|
||||
}
|
||||
else {
|
||||
//Make unit_feature opposite to this unit_feature on the street its third neighbor.
|
||||
unit_feature.properties.neighbors[2] = unit_pair[0],
|
||||
//Make unit_feature opposite to this unit_feature on the street's third neighbor this unit_feature.
|
||||
unit_pair[0].properties.neighbors[2] = unit_feature,
|
||||
|
||||
unit_pair[1] = unit_feature;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (unit_pair[0] !== null) {
|
||||
unit_features[0].push(unit_pair[0]);
|
||||
}
|
||||
|
||||
if (unit_pair[1] !== null) {
|
||||
unit_features[1].push(unit_pair[1]);
|
||||
}
|
||||
}
|
||||
|
||||
let unit_features_merged = [].concat(...unit_features);
|
||||
|
||||
return unit_features_merged;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find anchors for potential units. chors are the pairs of start
|
||||
* and end points along the street from which units may be constructed.
|
||||
* @private
|
||||
*
|
||||
* @param {Feature} street_feature - A GeoJSON feature object representing a street.
|
||||
* @returns {Array<Array<Feature>>} - array of pairs of points around which to anchor units along a street.
|
||||
*/
|
||||
function getUnitAnchors(street_feature, bounding_box) {
|
||||
let unit_anchors = [],
|
||||
unit_length = 14 / 1000, //Kilometers.
|
||||
unit_buffer = 3 / 1000, //Distance between units, kilometers.
|
||||
endpoint = street_feature.geometry.coordinates[street_feature.geometry.coordinates.length - 1],
|
||||
start_anchor = along(street_feature, 0),
|
||||
end_anchor = along(street_feature, unit_length),
|
||||
distance_along = unit_length;
|
||||
|
||||
while (end_anchor.geometry.coordinates != endpoint) {
|
||||
//Exclude proposed anchors if they're outside of the bounding box.
|
||||
start_coord = L.A.reversedCoordinates(start_anchor.geometry.coordinates),
|
||||
end_coord = L.A.reversedCoordinates(end_anchor.geometry.coordinates);
|
||||
if (L.latLngBounds(bounding_box).contains(start_coord) &&
|
||||
L.latLngBounds(bounding_box).contains(end_coord)) {
|
||||
unit_anchors.push([start_anchor, end_anchor]);
|
||||
}
|
||||
|
||||
//Find next pair of anchors.
|
||||
start_anchor = along(street_feature, distance_along + unit_buffer);
|
||||
end_anchor = along(street_feature, distance_along + unit_buffer + unit_length);
|
||||
|
||||
distance_along += unit_buffer + unit_length
|
||||
}
|
||||
|
||||
return unit_anchors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of units excluding units that overlap with streets.
|
||||
* @private
|
||||
*
|
||||
* @param {Array<Feature>} unit_features - ray of features representing units.
|
||||
* @param {Array<Layer>} street_layers - ray of Leaflet layers representing streets.
|
||||
* @returns {Array<Feature>} - unit_features, but with all units that intersect any streets removed.
|
||||
*/
|
||||
function unitsOutOfStreets(unit_features, street_layers) {
|
||||
let processed_unit_features = unit_features.slice();
|
||||
|
||||
street_layers.eachLayer(function(street_layer) {
|
||||
let street_feature = street_layer.feature;
|
||||
for (let unit_feature of processed_unit_features) {
|
||||
let intersection_exists = lineIntersect(street_feature, unit_feature).features.length > 0;
|
||||
if (intersection_exists) {
|
||||
processed_unit_features.splice(processed_unit_features.indexOf(unit_feature), 1, null);
|
||||
}
|
||||
}
|
||||
|
||||
processed_unit_features = processed_unit_features.filter(feature => feature === null ? false : true);
|
||||
});
|
||||
|
||||
|
||||
return processed_unit_features;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a polygon overlaps with any member of an array of polygons.
|
||||
* @private
|
||||
*
|
||||
* @param {Feature} polygon_feature - A geoJSON polygon feature.
|
||||
* @param {Array<Feature>} polygon_feature_array - array of geoJSON polygon features.
|
||||
* @returns {boolean} - Whether the polygon_feature overlaps with any one in the array.
|
||||
*/
|
||||
function noOverlaps(reference_polygon_feature, polygon_feature_array) {
|
||||
return true;
|
||||
for (feature_array_element of polygon_feature_array) {
|
||||
let overlap_exists = intersect(reference_polygon_feature, feature_array_element);
|
||||
if (overlap_exists) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Agentmap.prototype.buildingify = buildingify;
|
||||
|
||||
</code></pre>
|
||||
</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>Global</h3><ul><li><a href="global.html#agentify">agentify</a></li><li><a href="global.html#agentmapFactory">agentmapFactory</a></li><li><a href="global.html#buildingify">buildingify</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#layerCount">layerCount</a></li><li><a href="global.html#pointToCoordinateArray">pointToCoordinateArray</a></li><li><a href="global.html#reversedCoordinates">reversedCoordinates</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 Jul 31 2018 17:04:58 GMT-0400 (Eastern Daylight Time)
|
||||
</footer>
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
<script src="scripts/linenumber.js"> </script>
|
||||
</body>
|
||||
</html>
|
||||
BIN
docs/fonts/OpenSans-Bold-webfont.eot
Normal file
BIN
docs/fonts/OpenSans-Bold-webfont.eot
Normal file
Binary file not shown.
1830
docs/fonts/OpenSans-Bold-webfont.svg
Normal file
1830
docs/fonts/OpenSans-Bold-webfont.svg
Normal file
File diff suppressed because it is too large
Load Diff
|
After Width: | Height: | Size: 116 KiB |
BIN
docs/fonts/OpenSans-Bold-webfont.woff
Normal file
BIN
docs/fonts/OpenSans-Bold-webfont.woff
Normal file
Binary file not shown.
BIN
docs/fonts/OpenSans-BoldItalic-webfont.eot
Normal file
BIN
docs/fonts/OpenSans-BoldItalic-webfont.eot
Normal file
Binary file not shown.
1830
docs/fonts/OpenSans-BoldItalic-webfont.svg
Normal file
1830
docs/fonts/OpenSans-BoldItalic-webfont.svg
Normal file
File diff suppressed because it is too large
Load Diff
|
After Width: | Height: | Size: 118 KiB |
BIN
docs/fonts/OpenSans-BoldItalic-webfont.woff
Normal file
BIN
docs/fonts/OpenSans-BoldItalic-webfont.woff
Normal file
Binary file not shown.
BIN
docs/fonts/OpenSans-Italic-webfont.eot
Normal file
BIN
docs/fonts/OpenSans-Italic-webfont.eot
Normal file
Binary file not shown.
1830
docs/fonts/OpenSans-Italic-webfont.svg
Normal file
1830
docs/fonts/OpenSans-Italic-webfont.svg
Normal file
File diff suppressed because it is too large
Load Diff
|
After Width: | Height: | Size: 120 KiB |
BIN
docs/fonts/OpenSans-Italic-webfont.woff
Normal file
BIN
docs/fonts/OpenSans-Italic-webfont.woff
Normal file
Binary file not shown.
BIN
docs/fonts/OpenSans-Light-webfont.eot
Normal file
BIN
docs/fonts/OpenSans-Light-webfont.eot
Normal file
Binary file not shown.
1831
docs/fonts/OpenSans-Light-webfont.svg
Normal file
1831
docs/fonts/OpenSans-Light-webfont.svg
Normal file
File diff suppressed because it is too large
Load Diff
|
After Width: | Height: | Size: 114 KiB |
BIN
docs/fonts/OpenSans-Light-webfont.woff
Normal file
BIN
docs/fonts/OpenSans-Light-webfont.woff
Normal file
Binary file not shown.
BIN
docs/fonts/OpenSans-LightItalic-webfont.eot
Normal file
BIN
docs/fonts/OpenSans-LightItalic-webfont.eot
Normal file
Binary file not shown.
1835
docs/fonts/OpenSans-LightItalic-webfont.svg
Normal file
1835
docs/fonts/OpenSans-LightItalic-webfont.svg
Normal file
File diff suppressed because it is too large
Load Diff
|
After Width: | Height: | Size: 120 KiB |
BIN
docs/fonts/OpenSans-LightItalic-webfont.woff
Normal file
BIN
docs/fonts/OpenSans-LightItalic-webfont.woff
Normal file
Binary file not shown.
BIN
docs/fonts/OpenSans-Regular-webfont.eot
Normal file
BIN
docs/fonts/OpenSans-Regular-webfont.eot
Normal file
Binary file not shown.
1831
docs/fonts/OpenSans-Regular-webfont.svg
Normal file
1831
docs/fonts/OpenSans-Regular-webfont.svg
Normal file
File diff suppressed because it is too large
Load Diff
|
After Width: | Height: | Size: 117 KiB |
BIN
docs/fonts/OpenSans-Regular-webfont.woff
Normal file
BIN
docs/fonts/OpenSans-Regular-webfont.woff
Normal file
Binary file not shown.
2240
docs/global.html
Normal file
2240
docs/global.html
Normal file
File diff suppressed because it is too large
Load Diff
70
docs/index.html
Normal file
70
docs/index.html
Normal file
@ -0,0 +1,70 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>JSDoc: Home</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">Home</h1>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h3> </h3>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<section>
|
||||
<article><h1>AgentMaps</h1><p>DocsMake agent-based simulations on maps! Give it some neighborhood's OpenStreetMap data, and it'll generate buildings and give you utilities to embed and give rules to agents into the neighborhood.</p>
|
||||
<p>After including and loading Leaflet, include this script to use Agentmaps: https://unpkg.com/agentmaps@1/dist/agentmaps.js.</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>Global</h3><ul><li><a href="global.html#agentify">agentify</a></li><li><a href="global.html#agentmapFactory">agentmapFactory</a></li><li><a href="global.html#buildingify">buildingify</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#layerCount">layerCount</a></li><li><a href="global.html#pointToCoordinateArray">pointToCoordinateArray</a></li><li><a href="global.html#reversedCoordinates">reversedCoordinates</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 Jul 31 2018 17:04:58 GMT-0400 (Eastern Daylight Time)
|
||||
</footer>
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
<script src="scripts/linenumber.js"> </script>
|
||||
</body>
|
||||
</html>
|
||||
89
docs/jsdocs.js.html
Normal file
89
docs/jsdocs.js.html
Normal file
@ -0,0 +1,89 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>JSDoc: Source: jsdocs.js</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">Source: jsdocs.js</h1>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<section>
|
||||
<article>
|
||||
<pre class="prettyprint source linenums"><code>/* Extra JSDocs that aren't particular to any module */
|
||||
|
||||
/**
|
||||
* Represents a latitude/longitude pair. Preferably an instance of L.LatLng:
|
||||
* {@link https://leafletjs.com/reference-1.3.2.html#latlng}.
|
||||
*
|
||||
* @typedef {object} LatLng
|
||||
* @property {number} lat - A decimal latitude.
|
||||
* @property {number} lng - A decimal longitude.
|
||||
* @property {Place} [new_place] - A place (unit or street) associated with this LatLng.
|
||||
*/
|
||||
|
||||
/**
|
||||
* A GeoJSON feature object.
|
||||
*
|
||||
* @typedef {object} Feature
|
||||
* @property {string} type - Should be "Feature".
|
||||
* @property {object} properties - Non-geometric properties of the feature.
|
||||
* @property {object} geometry - Geometric properties of the feature (a GeoJSON spec of the feature's geometry).
|
||||
* @property {string} geometry.type - The feature's GeoJSON geometry type.
|
||||
* @property {Array} geometry.coordinates - The coordinates specifying the feature's geometry.
|
||||
* @see {@link http://geojson.org/}
|
||||
*/
|
||||
|
||||
/**
|
||||
* A GeoJSON {@link Feature} specifically for individual points.
|
||||
*
|
||||
* @typedef {Feature} Point
|
||||
* @property {Array} geometry.coordinates - A single array with 2 elements: [longitude, latitude].
|
||||
*/
|
||||
|
||||
/**
|
||||
* A place representing either a unit or a street.
|
||||
*
|
||||
* @typedef {object} Place
|
||||
* @property {number} [street] - The ID of a street in the agentmap's street layer group.
|
||||
* @property {number} [unit] - The ID of a unit in the agentmap's unit layer group.
|
||||
*/
|
||||
</code></pre>
|
||||
</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>Global</h3><ul><li><a href="global.html#agentify">agentify</a></li><li><a href="global.html#agentmapFactory">agentmapFactory</a></li><li><a href="global.html#buildingify">buildingify</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#layerCount">layerCount</a></li><li><a href="global.html#pointToCoordinateArray">pointToCoordinateArray</a></li><li><a href="global.html#reversedCoordinates">reversedCoordinates</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 Jul 31 2018 17:04:58 GMT-0400 (Eastern Daylight Time)
|
||||
</footer>
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
<script src="scripts/linenumber.js"> </script>
|
||||
</body>
|
||||
</html>
|
||||
25
docs/scripts/linenumber.js
Normal file
25
docs/scripts/linenumber.js
Normal file
@ -0,0 +1,25 @@
|
||||
/*global document */
|
||||
(function() {
|
||||
var source = document.getElementsByClassName('prettyprint source linenums');
|
||||
var i = 0;
|
||||
var lineNumber = 0;
|
||||
var lineId;
|
||||
var lines;
|
||||
var totalLines;
|
||||
var anchorHash;
|
||||
|
||||
if (source && source[0]) {
|
||||
anchorHash = document.location.hash.substring(1);
|
||||
lines = source[0].getElementsByTagName('li');
|
||||
totalLines = lines.length;
|
||||
|
||||
for (; i < totalLines; i++) {
|
||||
lineNumber++;
|
||||
lineId = 'line' + lineNumber;
|
||||
lines[i].id = lineId;
|
||||
if (lineId === anchorHash) {
|
||||
lines[i].className += ' selected';
|
||||
}
|
||||
}
|
||||
}
|
||||
})();
|
||||
202
docs/scripts/prettify/Apache-License-2.0.txt
Normal file
202
docs/scripts/prettify/Apache-License-2.0.txt
Normal file
@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
2
docs/scripts/prettify/lang-css.js
Normal file
2
docs/scripts/prettify/lang-css.js
Normal file
@ -0,0 +1,2 @@
|
||||
PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\f\r ]+/,null," \t\r\n"]],[["str",/^"(?:[^\n\f\r"\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*"/,null],["str",/^'(?:[^\n\f\r'\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*'/,null],["lang-css-str",/^url\(([^"')]*)\)/i],["kwd",/^(?:url|rgb|!important|@import|@page|@media|@charset|inherit)(?=[^\w-]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*)\s*:/i],["com",/^\/\*[^*]*\*+(?:[^*/][^*]*\*+)*\//],["com",
|
||||
/^(?:<\!--|--\>)/],["lit",/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],["lit",/^#[\da-f]{3,6}/i],["pln",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i],["pun",/^[^\s\w"']+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[["kwd",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[["str",/^[^"')]+/]]),["css-str"]);
|
||||
28
docs/scripts/prettify/prettify.js
Normal file
28
docs/scripts/prettify/prettify.js
Normal file
@ -0,0 +1,28 @@
|
||||
var q=null;window.PR_SHOULD_USE_CONTINUATION=!0;
|
||||
(function(){function L(a){function m(a){var f=a.charCodeAt(0);if(f!==92)return f;var b=a.charAt(1);return(f=r[b])?f:"0"<=b&&b<="7"?parseInt(a.substring(1),8):b==="u"||b==="x"?parseInt(a.substring(2),16):a.charCodeAt(1)}function e(a){if(a<32)return(a<16?"\\x0":"\\x")+a.toString(16);a=String.fromCharCode(a);if(a==="\\"||a==="-"||a==="["||a==="]")a="\\"+a;return a}function h(a){for(var f=a.substring(1,a.length-1).match(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\S\s]|[^\\]/g),a=
|
||||
[],b=[],o=f[0]==="^",c=o?1:0,i=f.length;c<i;++c){var j=f[c];if(/\\[bdsw]/i.test(j))a.push(j);else{var j=m(j),d;c+2<i&&"-"===f[c+1]?(d=m(f[c+2]),c+=2):d=j;b.push([j,d]);d<65||j>122||(d<65||j>90||b.push([Math.max(65,j)|32,Math.min(d,90)|32]),d<97||j>122||b.push([Math.max(97,j)&-33,Math.min(d,122)&-33]))}}b.sort(function(a,f){return a[0]-f[0]||f[1]-a[1]});f=[];j=[NaN,NaN];for(c=0;c<b.length;++c)i=b[c],i[0]<=j[1]+1?j[1]=Math.max(j[1],i[1]):f.push(j=i);b=["["];o&&b.push("^");b.push.apply(b,a);for(c=0;c<
|
||||
f.length;++c)i=f[c],b.push(e(i[0])),i[1]>i[0]&&(i[1]+1>i[0]&&b.push("-"),b.push(e(i[1])));b.push("]");return b.join("")}function y(a){for(var f=a.source.match(/\[(?:[^\\\]]|\\[\S\s])*]|\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\\d+|\\[^\dux]|\(\?[!:=]|[()^]|[^()[\\^]+/g),b=f.length,d=[],c=0,i=0;c<b;++c){var j=f[c];j==="("?++i:"\\"===j.charAt(0)&&(j=+j.substring(1))&&j<=i&&(d[j]=-1)}for(c=1;c<d.length;++c)-1===d[c]&&(d[c]=++t);for(i=c=0;c<b;++c)j=f[c],j==="("?(++i,d[i]===void 0&&(f[c]="(?:")):"\\"===j.charAt(0)&&
|
||||
(j=+j.substring(1))&&j<=i&&(f[c]="\\"+d[i]);for(i=c=0;c<b;++c)"^"===f[c]&&"^"!==f[c+1]&&(f[c]="");if(a.ignoreCase&&s)for(c=0;c<b;++c)j=f[c],a=j.charAt(0),j.length>=2&&a==="["?f[c]=h(j):a!=="\\"&&(f[c]=j.replace(/[A-Za-z]/g,function(a){a=a.charCodeAt(0);return"["+String.fromCharCode(a&-33,a|32)+"]"}));return f.join("")}for(var t=0,s=!1,l=!1,p=0,d=a.length;p<d;++p){var g=a[p];if(g.ignoreCase)l=!0;else if(/[a-z]/i.test(g.source.replace(/\\u[\da-f]{4}|\\x[\da-f]{2}|\\[^UXux]/gi,""))){s=!0;l=!1;break}}for(var r=
|
||||
{b:8,t:9,n:10,v:11,f:12,r:13},n=[],p=0,d=a.length;p<d;++p){g=a[p];if(g.global||g.multiline)throw Error(""+g);n.push("(?:"+y(g)+")")}return RegExp(n.join("|"),l?"gi":"g")}function M(a){function m(a){switch(a.nodeType){case 1:if(e.test(a.className))break;for(var g=a.firstChild;g;g=g.nextSibling)m(g);g=a.nodeName;if("BR"===g||"LI"===g)h[s]="\n",t[s<<1]=y++,t[s++<<1|1]=a;break;case 3:case 4:g=a.nodeValue,g.length&&(g=p?g.replace(/\r\n?/g,"\n"):g.replace(/[\t\n\r ]+/g," "),h[s]=g,t[s<<1]=y,y+=g.length,
|
||||
t[s++<<1|1]=a)}}var e=/(?:^|\s)nocode(?:\s|$)/,h=[],y=0,t=[],s=0,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=document.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);m(a);return{a:h.join("").replace(/\n$/,""),c:t}}function B(a,m,e,h){m&&(a={a:m,d:a},e(a),h.push.apply(h,a.e))}function x(a,m){function e(a){for(var l=a.d,p=[l,"pln"],d=0,g=a.a.match(y)||[],r={},n=0,z=g.length;n<z;++n){var f=g[n],b=r[f],o=void 0,c;if(typeof b===
|
||||
"string")c=!1;else{var i=h[f.charAt(0)];if(i)o=f.match(i[1]),b=i[0];else{for(c=0;c<t;++c)if(i=m[c],o=f.match(i[1])){b=i[0];break}o||(b="pln")}if((c=b.length>=5&&"lang-"===b.substring(0,5))&&!(o&&typeof o[1]==="string"))c=!1,b="src";c||(r[f]=b)}i=d;d+=f.length;if(c){c=o[1];var j=f.indexOf(c),k=j+c.length;o[2]&&(k=f.length-o[2].length,j=k-c.length);b=b.substring(5);B(l+i,f.substring(0,j),e,p);B(l+i+j,c,C(b,c),p);B(l+i+k,f.substring(k),e,p)}else p.push(l+i,b)}a.e=p}var h={},y;(function(){for(var e=a.concat(m),
|
||||
l=[],p={},d=0,g=e.length;d<g;++d){var r=e[d],n=r[3];if(n)for(var k=n.length;--k>=0;)h[n.charAt(k)]=r;r=r[1];n=""+r;p.hasOwnProperty(n)||(l.push(r),p[n]=q)}l.push(/[\S\s]/);y=L(l)})();var t=m.length;return e}function u(a){var m=[],e=[];a.tripleQuotedStrings?m.push(["str",/^(?:'''(?:[^'\\]|\\[\S\s]|''?(?=[^']))*(?:'''|$)|"""(?:[^"\\]|\\[\S\s]|""?(?=[^"]))*(?:"""|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$))/,q,"'\""]):a.multiLineStrings?m.push(["str",/^(?:'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$)|`(?:[^\\`]|\\[\S\s])*(?:`|$))/,
|
||||
q,"'\"`"]):m.push(["str",/^(?:'(?:[^\n\r'\\]|\\.)*(?:'|$)|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,q,"\"'"]);a.verbatimStrings&&e.push(["str",/^@"(?:[^"]|"")*(?:"|$)/,q]);var h=a.hashComments;h&&(a.cStyleComments?(h>1?m.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,q,"#"]):m.push(["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\n\r]*)/,q,"#"]),e.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,q])):m.push(["com",/^#[^\n\r]*/,
|
||||
q,"#"]));a.cStyleComments&&(e.push(["com",/^\/\/[^\n\r]*/,q]),e.push(["com",/^\/\*[\S\s]*?(?:\*\/|$)/,q]));a.regexLiterals&&e.push(["lang-regex",/^(?:^^\.?|[!+-]|!=|!==|#|%|%=|&|&&|&&=|&=|\(|\*|\*=|\+=|,|-=|->|\/|\/=|:|::|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|[?@[^]|\^=|\^\^|\^\^=|{|\||\|=|\|\||\|\|=|~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\s*(\/(?=[^*/])(?:[^/[\\]|\\[\S\s]|\[(?:[^\\\]]|\\[\S\s])*(?:]|$))+\/)/]);(h=a.types)&&e.push(["typ",h]);a=(""+a.keywords).replace(/^ | $/g,
|
||||
"");a.length&&e.push(["kwd",RegExp("^(?:"+a.replace(/[\s,]+/g,"|")+")\\b"),q]);m.push(["pln",/^\s+/,q," \r\n\t\xa0"]);e.push(["lit",/^@[$_a-z][\w$@]*/i,q],["typ",/^(?:[@_]?[A-Z]+[a-z][\w$@]*|\w+_t\b)/,q],["pln",/^[$_a-z][\w$@]*/i,q],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,q,"0123456789"],["pln",/^\\[\S\s]?/,q],["pun",/^.[^\s\w"-$'./@\\`]*/,q]);return x(m,e)}function D(a,m){function e(a){switch(a.nodeType){case 1:if(k.test(a.className))break;if("BR"===a.nodeName)h(a),
|
||||
a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)e(a);break;case 3:case 4:if(p){var b=a.nodeValue,d=b.match(t);if(d){var c=b.substring(0,d.index);a.nodeValue=c;(b=b.substring(d.index+d[0].length))&&a.parentNode.insertBefore(s.createTextNode(b),a.nextSibling);h(a);c||a.parentNode.removeChild(a)}}}}function h(a){function b(a,d){var e=d?a.cloneNode(!1):a,f=a.parentNode;if(f){var f=b(f,1),g=a.nextSibling;f.appendChild(e);for(var h=g;h;h=g)g=h.nextSibling,f.appendChild(h)}return e}
|
||||
for(;!a.nextSibling;)if(a=a.parentNode,!a)return;for(var a=b(a.nextSibling,0),e;(e=a.parentNode)&&e.nodeType===1;)a=e;d.push(a)}var k=/(?:^|\s)nocode(?:\s|$)/,t=/\r\n?|\n/,s=a.ownerDocument,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=s.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);for(l=s.createElement("LI");a.firstChild;)l.appendChild(a.firstChild);for(var d=[l],g=0;g<d.length;++g)e(d[g]);m===(m|0)&&d[0].setAttribute("value",
|
||||
m);var r=s.createElement("OL");r.className="linenums";for(var n=Math.max(0,m-1|0)||0,g=0,z=d.length;g<z;++g)l=d[g],l.className="L"+(g+n)%10,l.firstChild||l.appendChild(s.createTextNode("\xa0")),r.appendChild(l);a.appendChild(r)}function k(a,m){for(var e=m.length;--e>=0;){var h=m[e];A.hasOwnProperty(h)?window.console&&console.warn("cannot override language handler %s",h):A[h]=a}}function C(a,m){if(!a||!A.hasOwnProperty(a))a=/^\s*</.test(m)?"default-markup":"default-code";return A[a]}function E(a){var m=
|
||||
a.g;try{var e=M(a.h),h=e.a;a.a=h;a.c=e.c;a.d=0;C(m,h)(a);var k=/\bMSIE\b/.test(navigator.userAgent),m=/\n/g,t=a.a,s=t.length,e=0,l=a.c,p=l.length,h=0,d=a.e,g=d.length,a=0;d[g]=s;var r,n;for(n=r=0;n<g;)d[n]!==d[n+2]?(d[r++]=d[n++],d[r++]=d[n++]):n+=2;g=r;for(n=r=0;n<g;){for(var z=d[n],f=d[n+1],b=n+2;b+2<=g&&d[b+1]===f;)b+=2;d[r++]=z;d[r++]=f;n=b}for(d.length=r;h<p;){var o=l[h+2]||s,c=d[a+2]||s,b=Math.min(o,c),i=l[h+1],j;if(i.nodeType!==1&&(j=t.substring(e,b))){k&&(j=j.replace(m,"\r"));i.nodeValue=
|
||||
j;var u=i.ownerDocument,v=u.createElement("SPAN");v.className=d[a+1];var x=i.parentNode;x.replaceChild(v,i);v.appendChild(i);e<o&&(l[h+1]=i=u.createTextNode(t.substring(b,o)),x.insertBefore(i,v.nextSibling))}e=b;e>=o&&(h+=2);e>=c&&(a+=2)}}catch(w){"console"in window&&console.log(w&&w.stack?w.stack:w)}}var v=["break,continue,do,else,for,if,return,while"],w=[[v,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"],
|
||||
"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],F=[w,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],G=[w,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"],
|
||||
H=[G,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"],w=[w,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"],I=[v,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"],
|
||||
J=[v,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],v=[v,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],K=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/,N=/\S/,O=u({keywords:[F,H,w,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END"+
|
||||
I,J,v],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),A={};k(O,["default-code"]);k(x([],[["pln",/^[^<?]+/],["dec",/^<!\w[^>]*(?:>|$)/],["com",/^<\!--[\S\s]*?(?:--\>|$)/],["lang-",/^<\?([\S\s]+?)(?:\?>|$)/],["lang-",/^<%([\S\s]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",/^<xmp\b[^>]*>([\S\s]+?)<\/xmp\b[^>]*>/i],["lang-js",/^<script\b[^>]*>([\S\s]*?)(<\/script\b[^>]*>)/i],["lang-css",/^<style\b[^>]*>([\S\s]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),
|
||||
["default-markup","htm","html","mxml","xhtml","xml","xsl"]);k(x([["pln",/^\s+/,q," \t\r\n"],["atv",/^(?:"[^"]*"?|'[^']*'?)/,q,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w-.:]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^\s"'>]*(?:[^\s"'/>]|\/(?=\s)))/],["pun",/^[/<->]+/],["lang-js",/^on\w+\s*=\s*"([^"]+)"/i],["lang-js",/^on\w+\s*=\s*'([^']+)'/i],["lang-js",/^on\w+\s*=\s*([^\s"'>]+)/i],["lang-css",/^style\s*=\s*"([^"]+)"/i],["lang-css",/^style\s*=\s*'([^']+)'/i],["lang-css",
|
||||
/^style\s*=\s*([^\s"'>]+)/i]]),["in.tag"]);k(x([],[["atv",/^[\S\s]+/]]),["uq.val"]);k(u({keywords:F,hashComments:!0,cStyleComments:!0,types:K}),["c","cc","cpp","cxx","cyc","m"]);k(u({keywords:"null,true,false"}),["json"]);k(u({keywords:H,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:K}),["cs"]);k(u({keywords:G,cStyleComments:!0}),["java"]);k(u({keywords:v,hashComments:!0,multiLineStrings:!0}),["bsh","csh","sh"]);k(u({keywords:I,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}),
|
||||
["cv","py"]);k(u({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["perl","pl","pm"]);k(u({keywords:J,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb"]);k(u({keywords:w,cStyleComments:!0,regexLiterals:!0}),["js"]);k(u({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes",
|
||||
hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]);k(x([],[["str",/^[\S\s]+/]]),["regex"]);window.prettyPrintOne=function(a,m,e){var h=document.createElement("PRE");h.innerHTML=a;e&&D(h,e);E({g:m,i:e,h:h});return h.innerHTML};window.prettyPrint=function(a){function m(){for(var e=window.PR_SHOULD_USE_CONTINUATION?l.now()+250:Infinity;p<h.length&&l.now()<e;p++){var n=h[p],k=n.className;if(k.indexOf("prettyprint")>=0){var k=k.match(g),f,b;if(b=
|
||||
!k){b=n;for(var o=void 0,c=b.firstChild;c;c=c.nextSibling)var i=c.nodeType,o=i===1?o?b:c:i===3?N.test(c.nodeValue)?b:o:o;b=(f=o===b?void 0:o)&&"CODE"===f.tagName}b&&(k=f.className.match(g));k&&(k=k[1]);b=!1;for(o=n.parentNode;o;o=o.parentNode)if((o.tagName==="pre"||o.tagName==="code"||o.tagName==="xmp")&&o.className&&o.className.indexOf("prettyprint")>=0){b=!0;break}b||((b=(b=n.className.match(/\blinenums\b(?::(\d+))?/))?b[1]&&b[1].length?+b[1]:!0:!1)&&D(n,b),d={g:k,h:n,i:b},E(d))}}p<h.length?setTimeout(m,
|
||||
250):a&&a()}for(var e=[document.getElementsByTagName("pre"),document.getElementsByTagName("code"),document.getElementsByTagName("xmp")],h=[],k=0;k<e.length;++k)for(var t=0,s=e[k].length;t<s;++t)h.push(e[k][t]);var e=q,l=Date;l.now||(l={now:function(){return+new Date}});var p=0,d,g=/\blang(?:uage)?-([\w.]+)(?!\S)/;m()};window.PR={createSimpleLexer:x,registerLangHandler:k,sourceDecorator:u,PR_ATTRIB_NAME:"atn",PR_ATTRIB_VALUE:"atv",PR_COMMENT:"com",PR_DECLARATION:"dec",PR_KEYWORD:"kwd",PR_LITERAL:"lit",
|
||||
PR_NOCODE:"nocode",PR_PLAIN:"pln",PR_PUNCTUATION:"pun",PR_SOURCE:"src",PR_STRING:"str",PR_TAG:"tag",PR_TYPE:"typ"}})();
|
||||
358
docs/styles/jsdoc-default.css
Normal file
358
docs/styles/jsdoc-default.css
Normal file
@ -0,0 +1,358 @@
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
src: url('../fonts/OpenSans-Regular-webfont.eot');
|
||||
src:
|
||||
local('Open Sans'),
|
||||
local('OpenSans'),
|
||||
url('../fonts/OpenSans-Regular-webfont.eot?#iefix') format('embedded-opentype'),
|
||||
url('../fonts/OpenSans-Regular-webfont.woff') format('woff'),
|
||||
url('../fonts/OpenSans-Regular-webfont.svg#open_sansregular') format('svg');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Open Sans Light';
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
src: url('../fonts/OpenSans-Light-webfont.eot');
|
||||
src:
|
||||
local('Open Sans Light'),
|
||||
local('OpenSans Light'),
|
||||
url('../fonts/OpenSans-Light-webfont.eot?#iefix') format('embedded-opentype'),
|
||||
url('../fonts/OpenSans-Light-webfont.woff') format('woff'),
|
||||
url('../fonts/OpenSans-Light-webfont.svg#open_sanslight') format('svg');
|
||||
}
|
||||
|
||||
html
|
||||
{
|
||||
overflow: auto;
|
||||
background-color: #fff;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
body
|
||||
{
|
||||
font-family: 'Open Sans', sans-serif;
|
||||
line-height: 1.5;
|
||||
color: #4d4e53;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
a, a:visited, a:active {
|
||||
color: #0095dd;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
header
|
||||
{
|
||||
display: block;
|
||||
padding: 0px 4px;
|
||||
}
|
||||
|
||||
tt, code, kbd, samp {
|
||||
font-family: Consolas, Monaco, 'Andale Mono', monospace;
|
||||
}
|
||||
|
||||
.class-description {
|
||||
font-size: 130%;
|
||||
line-height: 140%;
|
||||
margin-bottom: 1em;
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.class-description:empty {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#main {
|
||||
float: left;
|
||||
width: 70%;
|
||||
}
|
||||
|
||||
article dl {
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
article img {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
section
|
||||
{
|
||||
display: block;
|
||||
background-color: #fff;
|
||||
padding: 12px 24px;
|
||||
border-bottom: 1px solid #ccc;
|
||||
margin-right: 30px;
|
||||
}
|
||||
|
||||
.variation {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.signature-attributes {
|
||||
font-size: 60%;
|
||||
color: #aaa;
|
||||
font-style: italic;
|
||||
font-weight: lighter;
|
||||
}
|
||||
|
||||
nav
|
||||
{
|
||||
display: block;
|
||||
float: right;
|
||||
margin-top: 28px;
|
||||
width: 30%;
|
||||
box-sizing: border-box;
|
||||
border-left: 1px solid #ccc;
|
||||
padding-left: 16px;
|
||||
}
|
||||
|
||||
nav ul {
|
||||
font-family: 'Lucida Grande', 'Lucida Sans Unicode', arial, sans-serif;
|
||||
font-size: 100%;
|
||||
line-height: 17px;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
nav ul a, nav ul a:visited, nav ul a:active {
|
||||
font-family: Consolas, Monaco, 'Andale Mono', monospace;
|
||||
line-height: 18px;
|
||||
color: #4D4E53;
|
||||
}
|
||||
|
||||
nav h3 {
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
nav li {
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
footer {
|
||||
display: block;
|
||||
padding: 6px;
|
||||
margin-top: 12px;
|
||||
font-style: italic;
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4 {
|
||||
font-weight: 200;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
h1
|
||||
{
|
||||
font-family: 'Open Sans Light', sans-serif;
|
||||
font-size: 48px;
|
||||
letter-spacing: -2px;
|
||||
margin: 12px 24px 20px;
|
||||
}
|
||||
|
||||
h2, h3.subsection-title
|
||||
{
|
||||
font-size: 30px;
|
||||
font-weight: 700;
|
||||
letter-spacing: -1px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
h3
|
||||
{
|
||||
font-size: 24px;
|
||||
letter-spacing: -0.5px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
h4
|
||||
{
|
||||
font-size: 18px;
|
||||
letter-spacing: -0.33px;
|
||||
margin-bottom: 12px;
|
||||
color: #4d4e53;
|
||||
}
|
||||
|
||||
h5, .container-overview .subsection-title
|
||||
{
|
||||
font-size: 120%;
|
||||
font-weight: bold;
|
||||
letter-spacing: -0.01em;
|
||||
margin: 8px 0 3px 0;
|
||||
}
|
||||
|
||||
h6
|
||||
{
|
||||
font-size: 100%;
|
||||
letter-spacing: -0.01em;
|
||||
margin: 6px 0 3px 0;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
table
|
||||
{
|
||||
border-spacing: 0;
|
||||
border: 0;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
td, th
|
||||
{
|
||||
border: 1px solid #ddd;
|
||||
margin: 0px;
|
||||
text-align: left;
|
||||
vertical-align: top;
|
||||
padding: 4px 6px;
|
||||
display: table-cell;
|
||||
}
|
||||
|
||||
thead tr
|
||||
{
|
||||
background-color: #ddd;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
th { border-right: 1px solid #aaa; }
|
||||
tr > th:last-child { border-right: 1px solid #ddd; }
|
||||
|
||||
.ancestors, .attribs { color: #999; }
|
||||
.ancestors a, .attribs a
|
||||
{
|
||||
color: #999 !important;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.clear
|
||||
{
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.important
|
||||
{
|
||||
font-weight: bold;
|
||||
color: #950B02;
|
||||
}
|
||||
|
||||
.yes-def {
|
||||
text-indent: -1000px;
|
||||
}
|
||||
|
||||
.type-signature {
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
.name, .signature {
|
||||
font-family: Consolas, Monaco, 'Andale Mono', monospace;
|
||||
}
|
||||
|
||||
.details { margin-top: 14px; border-left: 2px solid #DDD; }
|
||||
.details dt { width: 120px; float: left; padding-left: 10px; padding-top: 6px; }
|
||||
.details dd { margin-left: 70px; }
|
||||
.details ul { margin: 0; }
|
||||
.details ul { list-style-type: none; }
|
||||
.details li { margin-left: 30px; padding-top: 6px; }
|
||||
.details pre.prettyprint { margin: 0 }
|
||||
.details .object-value { padding-top: 0; }
|
||||
|
||||
.description {
|
||||
margin-bottom: 1em;
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.code-caption
|
||||
{
|
||||
font-style: italic;
|
||||
font-size: 107%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.prettyprint
|
||||
{
|
||||
border: 1px solid #ddd;
|
||||
width: 80%;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.prettyprint.source {
|
||||
width: inherit;
|
||||
}
|
||||
|
||||
.prettyprint code
|
||||
{
|
||||
font-size: 100%;
|
||||
line-height: 18px;
|
||||
display: block;
|
||||
padding: 4px 12px;
|
||||
margin: 0;
|
||||
background-color: #fff;
|
||||
color: #4D4E53;
|
||||
}
|
||||
|
||||
.prettyprint code span.line
|
||||
{
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.prettyprint.linenums
|
||||
{
|
||||
padding-left: 70px;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.prettyprint.linenums ol
|
||||
{
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.prettyprint.linenums li
|
||||
{
|
||||
border-left: 3px #ddd solid;
|
||||
}
|
||||
|
||||
.prettyprint.linenums li.selected,
|
||||
.prettyprint.linenums li.selected *
|
||||
{
|
||||
background-color: lightyellow;
|
||||
}
|
||||
|
||||
.prettyprint.linenums li *
|
||||
{
|
||||
-webkit-user-select: text;
|
||||
-moz-user-select: text;
|
||||
-ms-user-select: text;
|
||||
user-select: text;
|
||||
}
|
||||
|
||||
.params .name, .props .name, .name code {
|
||||
color: #4D4E53;
|
||||
font-family: Consolas, Monaco, 'Andale Mono', monospace;
|
||||
font-size: 100%;
|
||||
}
|
||||
|
||||
.params td.description > p:first-child,
|
||||
.props td.description > p:first-child
|
||||
{
|
||||
margin-top: 0;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.params td.description > p:last-child,
|
||||
.props td.description > p:last-child
|
||||
{
|
||||
margin-bottom: 0;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.disabled {
|
||||
color: #454545;
|
||||
}
|
||||
111
docs/styles/prettify-jsdoc.css
Normal file
111
docs/styles/prettify-jsdoc.css
Normal file
@ -0,0 +1,111 @@
|
||||
/* JSDoc prettify.js theme */
|
||||
|
||||
/* plain text */
|
||||
.pln {
|
||||
color: #000000;
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
/* string content */
|
||||
.str {
|
||||
color: #006400;
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
/* a keyword */
|
||||
.kwd {
|
||||
color: #000000;
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
/* a comment */
|
||||
.com {
|
||||
font-weight: normal;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/* a type name */
|
||||
.typ {
|
||||
color: #000000;
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
/* a literal value */
|
||||
.lit {
|
||||
color: #006400;
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
/* punctuation */
|
||||
.pun {
|
||||
color: #000000;
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
/* lisp open bracket */
|
||||
.opn {
|
||||
color: #000000;
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
/* lisp close bracket */
|
||||
.clo {
|
||||
color: #000000;
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
/* a markup tag name */
|
||||
.tag {
|
||||
color: #006400;
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
/* a markup attribute name */
|
||||
.atn {
|
||||
color: #006400;
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
/* a markup attribute value */
|
||||
.atv {
|
||||
color: #006400;
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
/* a declaration */
|
||||
.dec {
|
||||
color: #000000;
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
/* a variable name */
|
||||
.var {
|
||||
color: #000000;
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
/* a function name */
|
||||
.fun {
|
||||
color: #000000;
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
/* Specify class=linenums on a pre to get line numbering */
|
||||
ol.linenums {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
132
docs/styles/prettify-tomorrow.css
Normal file
132
docs/styles/prettify-tomorrow.css
Normal file
@ -0,0 +1,132 @@
|
||||
/* Tomorrow Theme */
|
||||
/* Original theme - https://github.com/chriskempson/tomorrow-theme */
|
||||
/* Pretty printing styles. Used with prettify.js. */
|
||||
/* SPAN elements with the classes below are added by prettyprint. */
|
||||
/* plain text */
|
||||
.pln {
|
||||
color: #4d4d4c; }
|
||||
|
||||
@media screen {
|
||||
/* string content */
|
||||
.str {
|
||||
color: #718c00; }
|
||||
|
||||
/* a keyword */
|
||||
.kwd {
|
||||
color: #8959a8; }
|
||||
|
||||
/* a comment */
|
||||
.com {
|
||||
color: #8e908c; }
|
||||
|
||||
/* a type name */
|
||||
.typ {
|
||||
color: #4271ae; }
|
||||
|
||||
/* a literal value */
|
||||
.lit {
|
||||
color: #f5871f; }
|
||||
|
||||
/* punctuation */
|
||||
.pun {
|
||||
color: #4d4d4c; }
|
||||
|
||||
/* lisp open bracket */
|
||||
.opn {
|
||||
color: #4d4d4c; }
|
||||
|
||||
/* lisp close bracket */
|
||||
.clo {
|
||||
color: #4d4d4c; }
|
||||
|
||||
/* a markup tag name */
|
||||
.tag {
|
||||
color: #c82829; }
|
||||
|
||||
/* a markup attribute name */
|
||||
.atn {
|
||||
color: #f5871f; }
|
||||
|
||||
/* a markup attribute value */
|
||||
.atv {
|
||||
color: #3e999f; }
|
||||
|
||||
/* a declaration */
|
||||
.dec {
|
||||
color: #f5871f; }
|
||||
|
||||
/* a variable name */
|
||||
.var {
|
||||
color: #c82829; }
|
||||
|
||||
/* a function name */
|
||||
.fun {
|
||||
color: #4271ae; } }
|
||||
/* Use higher contrast and text-weight for printable form. */
|
||||
@media print, projection {
|
||||
.str {
|
||||
color: #060; }
|
||||
|
||||
.kwd {
|
||||
color: #006;
|
||||
font-weight: bold; }
|
||||
|
||||
.com {
|
||||
color: #600;
|
||||
font-style: italic; }
|
||||
|
||||
.typ {
|
||||
color: #404;
|
||||
font-weight: bold; }
|
||||
|
||||
.lit {
|
||||
color: #044; }
|
||||
|
||||
.pun, .opn, .clo {
|
||||
color: #440; }
|
||||
|
||||
.tag {
|
||||
color: #006;
|
||||
font-weight: bold; }
|
||||
|
||||
.atn {
|
||||
color: #404; }
|
||||
|
||||
.atv {
|
||||
color: #060; } }
|
||||
/* Style */
|
||||
/*
|
||||
pre.prettyprint {
|
||||
background: white;
|
||||
font-family: Consolas, Monaco, 'Andale Mono', monospace;
|
||||
font-size: 12px;
|
||||
line-height: 1.5;
|
||||
border: 1px solid #ccc;
|
||||
padding: 10px; }
|
||||
*/
|
||||
|
||||
/* Specify class=linenums on a pre to get line numbering */
|
||||
ol.linenums {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0; }
|
||||
|
||||
/* IE indents via margin-left */
|
||||
li.L0,
|
||||
li.L1,
|
||||
li.L2,
|
||||
li.L3,
|
||||
li.L4,
|
||||
li.L5,
|
||||
li.L6,
|
||||
li.L7,
|
||||
li.L8,
|
||||
li.L9 {
|
||||
/* */ }
|
||||
|
||||
/* Alternate shading for lines */
|
||||
li.L1,
|
||||
li.L3,
|
||||
li.L5,
|
||||
li.L7,
|
||||
li.L9 {
|
||||
/* */ }
|
||||
171
docs/utils.js.html
Normal file
171
docs/utils.js.html
Normal file
@ -0,0 +1,171 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>JSDoc: Source: utils.js</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">Source: utils.js</h1>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<section>
|
||||
<article>
|
||||
<pre class="prettyprint source linenums"><code>/**
|
||||
* Given a geoJSON geometry object's coordinates, return the object, but with
|
||||
* all the coordinates reversed. <br /point.geometry && point.geometry.coordinates && >
|
||||
*
|
||||
* Why? GeoJSON coordinates are in lngLat format by default, while Leaflet uses latLng.
|
||||
* L.geoJSON will auto-reverse the order of a GeoJSON object's coordinates, as it
|
||||
* expects geoJSON coordinates to be lngLat. However, normal, non-GeoJSON-specific Leaflet
|
||||
* methods expect Leaflet's latLng pairs and won't auto-reverse, so we have to do that
|
||||
* manually if we're preprocessing the GeoJSON data before passing it to L.geoJSON.
|
||||
*
|
||||
* @param {Array<number|Array<number|Array<number>>>} coordinates - GeoJSON coordinates for a point, (multi-)line, or (multi-)polygon.
|
||||
* @returns {Array<number|Array<number|Array<number>>>} - Reversed geoJSON coordinates for a point, (multi-)line, or (multi-)polygon.
|
||||
*/
|
||||
function reversedCoordinates(coordinates) {
|
||||
let reversed = coordinates.slice();
|
||||
if (typeof coordinates[0] != "number") {
|
||||
for (let inner_coordinates of coordinates) {
|
||||
reversed.splice(reversed.indexOf(inner_coordinates), 1, reversedCoordinates(inner_coordinates));
|
||||
}
|
||||
}
|
||||
else {
|
||||
reversed = [coordinates[1], coordinates[0]];
|
||||
}
|
||||
|
||||
return reversed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an array, check whether it can represent the coordinates of a point.
|
||||
*
|
||||
* @param {Array} array - Array to check.
|
||||
* @returns {boolean} - Whether the array can be the coordinates of a point.
|
||||
*/
|
||||
function isPointCoordinates(array) {
|
||||
if (array.length !== 2 ||
|
||||
typeof(array[0]) !== "number" ||
|
||||
typeof(array[1]) !== "number") {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given either a GeoJSON feature, L.latLng, or coordinate array containing the coordinates of a point,
|
||||
* return an array of the coordinates.
|
||||
*
|
||||
* @params {Point|Array<number>|LatLng} point - The data containing the point's coordinates (latitude & longitude).
|
||||
* @returns {Array<number>} - Array of the point's coordinates. I.e.: [lng, lat].
|
||||
*/
|
||||
function pointToCoordinateArray(point) {
|
||||
let coordinate_array;
|
||||
|
||||
if (typeof(point.lat) === "number" && typeof(point.lng) === "number") {
|
||||
coordinate_array = [point.lng, point.lat];
|
||||
}
|
||||
else if (point.geometry && point.geometry.coordinates && isPointCoordinates(point.geometry.coordinates)) {
|
||||
coordinate_array = point.geometry.coordinates;
|
||||
}
|
||||
else if (isPointCoordinates(point)) {
|
||||
coordinate_array = point;
|
||||
}
|
||||
else {
|
||||
throw new Error("Invalid point: point must either be array of 2 coordinates, or an L.latLng.");
|
||||
}
|
||||
|
||||
return coordinate_array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given two coordinate arrays, get their intersection.
|
||||
*
|
||||
* @param {array<array<number>>} arr_a - Array of coordinate pairs.
|
||||
* @param {array<array<number>>} arr_b - Array of coordinate pairs.
|
||||
* @param {array<number>} ids - 2-element array whose elements are IDs for arr_a and arr_b respectively.
|
||||
*
|
||||
* @returns {Array<Array<number|Object<number, number>>>} - Array whose elements are the intersections' cooridinates if
|
||||
* ids is empty, or otherwise whose elements are arrays each of whose first element is an
|
||||
* intersection's coordinates and whose second element is an object mapping each array's ID (supplied by ids)
|
||||
* to the index of the intersecting coordinate-pair in that array.
|
||||
*/
|
||||
function getIntersections(arr_a, arr_b, ids = []) {
|
||||
let intersections = [];
|
||||
|
||||
for (let i = 0; i < arr_a.length; i++) {
|
||||
let el_a = arr_a[i];
|
||||
|
||||
for (let j = 0; j < arr_b.length; j++) {
|
||||
let el_b = arr_b[j];
|
||||
|
||||
if (isPointCoordinates(el_a) && isPointCoordinates(el_b)) {
|
||||
if (el_a[0] === el_b[0] && el_a[1] === el_b[1]) {
|
||||
let new_intersection;
|
||||
|
||||
if (ids.length === 2) {
|
||||
let identified_intersections = {};
|
||||
identified_intersections[ids[0]] = i,
|
||||
identified_intersections[ids[1]] = j,
|
||||
new_intersection = [el_a, identified_intersections];
|
||||
}
|
||||
else {
|
||||
new_intersection = el_a;
|
||||
}
|
||||
|
||||
intersections.push(new_intersection);
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new Error("Every element of each array must be a coordinate pair array.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return intersections;
|
||||
}
|
||||
|
||||
exports.getIntersections = getIntersections;
|
||||
exports.reversedCoordinates = reversedCoordinates;
|
||||
exports.isPointCoordinates = isPointCoordinates;
|
||||
exports.pointToCoordinateArray = pointToCoordinateArray;
|
||||
</code></pre>
|
||||
</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>Global</h3><ul><li><a href="global.html#agentify">agentify</a></li><li><a href="global.html#agentmapFactory">agentmapFactory</a></li><li><a href="global.html#buildingify">buildingify</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#layerCount">layerCount</a></li><li><a href="global.html#pointToCoordinateArray">pointToCoordinateArray</a></li><li><a href="global.html#reversedCoordinates">reversedCoordinates</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 Jul 31 2018 17:04:58 GMT-0400 (Eastern Daylight Time)
|
||||
</footer>
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
<script src="scripts/linenumber.js"> </script>
|
||||
</body>
|
||||
</html>
|
||||
358
styles/jsdoc-default.css
Normal file
358
styles/jsdoc-default.css
Normal file
@ -0,0 +1,358 @@
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
src: url('../fonts/OpenSans-Regular-webfont.eot');
|
||||
src:
|
||||
local('Open Sans'),
|
||||
local('OpenSans'),
|
||||
url('../fonts/OpenSans-Regular-webfont.eot?#iefix') format('embedded-opentype'),
|
||||
url('../fonts/OpenSans-Regular-webfont.woff') format('woff'),
|
||||
url('../fonts/OpenSans-Regular-webfont.svg#open_sansregular') format('svg');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Open Sans Light';
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
src: url('../fonts/OpenSans-Light-webfont.eot');
|
||||
src:
|
||||
local('Open Sans Light'),
|
||||
local('OpenSans Light'),
|
||||
url('../fonts/OpenSans-Light-webfont.eot?#iefix') format('embedded-opentype'),
|
||||
url('../fonts/OpenSans-Light-webfont.woff') format('woff'),
|
||||
url('../fonts/OpenSans-Light-webfont.svg#open_sanslight') format('svg');
|
||||
}
|
||||
|
||||
html
|
||||
{
|
||||
overflow: auto;
|
||||
background-color: #fff;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
body
|
||||
{
|
||||
font-family: 'Open Sans', sans-serif;
|
||||
line-height: 1.5;
|
||||
color: #4d4e53;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
a, a:visited, a:active {
|
||||
color: #0095dd;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
header
|
||||
{
|
||||
display: block;
|
||||
padding: 0px 4px;
|
||||
}
|
||||
|
||||
tt, code, kbd, samp {
|
||||
font-family: Consolas, Monaco, 'Andale Mono', monospace;
|
||||
}
|
||||
|
||||
.class-description {
|
||||
font-size: 130%;
|
||||
line-height: 140%;
|
||||
margin-bottom: 1em;
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.class-description:empty {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#main {
|
||||
float: left;
|
||||
width: 70%;
|
||||
}
|
||||
|
||||
article dl {
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
article img {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
section
|
||||
{
|
||||
display: block;
|
||||
background-color: #fff;
|
||||
padding: 12px 24px;
|
||||
border-bottom: 1px solid #ccc;
|
||||
margin-right: 30px;
|
||||
}
|
||||
|
||||
.variation {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.signature-attributes {
|
||||
font-size: 60%;
|
||||
color: #aaa;
|
||||
font-style: italic;
|
||||
font-weight: lighter;
|
||||
}
|
||||
|
||||
nav
|
||||
{
|
||||
display: block;
|
||||
float: right;
|
||||
margin-top: 28px;
|
||||
width: 30%;
|
||||
box-sizing: border-box;
|
||||
border-left: 1px solid #ccc;
|
||||
padding-left: 16px;
|
||||
}
|
||||
|
||||
nav ul {
|
||||
font-family: 'Lucida Grande', 'Lucida Sans Unicode', arial, sans-serif;
|
||||
font-size: 100%;
|
||||
line-height: 17px;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
nav ul a, nav ul a:visited, nav ul a:active {
|
||||
font-family: Consolas, Monaco, 'Andale Mono', monospace;
|
||||
line-height: 18px;
|
||||
color: #4D4E53;
|
||||
}
|
||||
|
||||
nav h3 {
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
nav li {
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
footer {
|
||||
display: block;
|
||||
padding: 6px;
|
||||
margin-top: 12px;
|
||||
font-style: italic;
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4 {
|
||||
font-weight: 200;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
h1
|
||||
{
|
||||
font-family: 'Open Sans Light', sans-serif;
|
||||
font-size: 48px;
|
||||
letter-spacing: -2px;
|
||||
margin: 12px 24px 20px;
|
||||
}
|
||||
|
||||
h2, h3.subsection-title
|
||||
{
|
||||
font-size: 30px;
|
||||
font-weight: 700;
|
||||
letter-spacing: -1px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
h3
|
||||
{
|
||||
font-size: 24px;
|
||||
letter-spacing: -0.5px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
h4
|
||||
{
|
||||
font-size: 18px;
|
||||
letter-spacing: -0.33px;
|
||||
margin-bottom: 12px;
|
||||
color: #4d4e53;
|
||||
}
|
||||
|
||||
h5, .container-overview .subsection-title
|
||||
{
|
||||
font-size: 120%;
|
||||
font-weight: bold;
|
||||
letter-spacing: -0.01em;
|
||||
margin: 8px 0 3px 0;
|
||||
}
|
||||
|
||||
h6
|
||||
{
|
||||
font-size: 100%;
|
||||
letter-spacing: -0.01em;
|
||||
margin: 6px 0 3px 0;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
table
|
||||
{
|
||||
border-spacing: 0;
|
||||
border: 0;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
td, th
|
||||
{
|
||||
border: 1px solid #ddd;
|
||||
margin: 0px;
|
||||
text-align: left;
|
||||
vertical-align: top;
|
||||
padding: 4px 6px;
|
||||
display: table-cell;
|
||||
}
|
||||
|
||||
thead tr
|
||||
{
|
||||
background-color: #ddd;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
th { border-right: 1px solid #aaa; }
|
||||
tr > th:last-child { border-right: 1px solid #ddd; }
|
||||
|
||||
.ancestors, .attribs { color: #999; }
|
||||
.ancestors a, .attribs a
|
||||
{
|
||||
color: #999 !important;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.clear
|
||||
{
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.important
|
||||
{
|
||||
font-weight: bold;
|
||||
color: #950B02;
|
||||
}
|
||||
|
||||
.yes-def {
|
||||
text-indent: -1000px;
|
||||
}
|
||||
|
||||
.type-signature {
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
.name, .signature {
|
||||
font-family: Consolas, Monaco, 'Andale Mono', monospace;
|
||||
}
|
||||
|
||||
.details { margin-top: 14px; border-left: 2px solid #DDD; }
|
||||
.details dt { width: 120px; float: left; padding-left: 10px; padding-top: 6px; }
|
||||
.details dd { margin-left: 70px; }
|
||||
.details ul { margin: 0; }
|
||||
.details ul { list-style-type: none; }
|
||||
.details li { margin-left: 30px; padding-top: 6px; }
|
||||
.details pre.prettyprint { margin: 0 }
|
||||
.details .object-value { padding-top: 0; }
|
||||
|
||||
.description {
|
||||
margin-bottom: 1em;
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.code-caption
|
||||
{
|
||||
font-style: italic;
|
||||
font-size: 107%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.prettyprint
|
||||
{
|
||||
border: 1px solid #ddd;
|
||||
width: 80%;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.prettyprint.source {
|
||||
width: inherit;
|
||||
}
|
||||
|
||||
.prettyprint code
|
||||
{
|
||||
font-size: 100%;
|
||||
line-height: 18px;
|
||||
display: block;
|
||||
padding: 4px 12px;
|
||||
margin: 0;
|
||||
background-color: #fff;
|
||||
color: #4D4E53;
|
||||
}
|
||||
|
||||
.prettyprint code span.line
|
||||
{
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.prettyprint.linenums
|
||||
{
|
||||
padding-left: 70px;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.prettyprint.linenums ol
|
||||
{
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.prettyprint.linenums li
|
||||
{
|
||||
border-left: 3px #ddd solid;
|
||||
}
|
||||
|
||||
.prettyprint.linenums li.selected,
|
||||
.prettyprint.linenums li.selected *
|
||||
{
|
||||
background-color: lightyellow;
|
||||
}
|
||||
|
||||
.prettyprint.linenums li *
|
||||
{
|
||||
-webkit-user-select: text;
|
||||
-moz-user-select: text;
|
||||
-ms-user-select: text;
|
||||
user-select: text;
|
||||
}
|
||||
|
||||
.params .name, .props .name, .name code {
|
||||
color: #4D4E53;
|
||||
font-family: Consolas, Monaco, 'Andale Mono', monospace;
|
||||
font-size: 100%;
|
||||
}
|
||||
|
||||
.params td.description > p:first-child,
|
||||
.props td.description > p:first-child
|
||||
{
|
||||
margin-top: 0;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.params td.description > p:last-child,
|
||||
.props td.description > p:last-child
|
||||
{
|
||||
margin-bottom: 0;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.disabled {
|
||||
color: #454545;
|
||||
}
|
||||
111
styles/prettify-jsdoc.css
Normal file
111
styles/prettify-jsdoc.css
Normal file
@ -0,0 +1,111 @@
|
||||
/* JSDoc prettify.js theme */
|
||||
|
||||
/* plain text */
|
||||
.pln {
|
||||
color: #000000;
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
/* string content */
|
||||
.str {
|
||||
color: #006400;
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
/* a keyword */
|
||||
.kwd {
|
||||
color: #000000;
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
/* a comment */
|
||||
.com {
|
||||
font-weight: normal;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/* a type name */
|
||||
.typ {
|
||||
color: #000000;
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
/* a literal value */
|
||||
.lit {
|
||||
color: #006400;
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
/* punctuation */
|
||||
.pun {
|
||||
color: #000000;
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
/* lisp open bracket */
|
||||
.opn {
|
||||
color: #000000;
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
/* lisp close bracket */
|
||||
.clo {
|
||||
color: #000000;
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
/* a markup tag name */
|
||||
.tag {
|
||||
color: #006400;
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
/* a markup attribute name */
|
||||
.atn {
|
||||
color: #006400;
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
/* a markup attribute value */
|
||||
.atv {
|
||||
color: #006400;
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
/* a declaration */
|
||||
.dec {
|
||||
color: #000000;
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
/* a variable name */
|
||||
.var {
|
||||
color: #000000;
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
/* a function name */
|
||||
.fun {
|
||||
color: #000000;
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
/* Specify class=linenums on a pre to get line numbering */
|
||||
ol.linenums {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
132
styles/prettify-tomorrow.css
Normal file
132
styles/prettify-tomorrow.css
Normal file
@ -0,0 +1,132 @@
|
||||
/* Tomorrow Theme */
|
||||
/* Original theme - https://github.com/chriskempson/tomorrow-theme */
|
||||
/* Pretty printing styles. Used with prettify.js. */
|
||||
/* SPAN elements with the classes below are added by prettyprint. */
|
||||
/* plain text */
|
||||
.pln {
|
||||
color: #4d4d4c; }
|
||||
|
||||
@media screen {
|
||||
/* string content */
|
||||
.str {
|
||||
color: #718c00; }
|
||||
|
||||
/* a keyword */
|
||||
.kwd {
|
||||
color: #8959a8; }
|
||||
|
||||
/* a comment */
|
||||
.com {
|
||||
color: #8e908c; }
|
||||
|
||||
/* a type name */
|
||||
.typ {
|
||||
color: #4271ae; }
|
||||
|
||||
/* a literal value */
|
||||
.lit {
|
||||
color: #f5871f; }
|
||||
|
||||
/* punctuation */
|
||||
.pun {
|
||||
color: #4d4d4c; }
|
||||
|
||||
/* lisp open bracket */
|
||||
.opn {
|
||||
color: #4d4d4c; }
|
||||
|
||||
/* lisp close bracket */
|
||||
.clo {
|
||||
color: #4d4d4c; }
|
||||
|
||||
/* a markup tag name */
|
||||
.tag {
|
||||
color: #c82829; }
|
||||
|
||||
/* a markup attribute name */
|
||||
.atn {
|
||||
color: #f5871f; }
|
||||
|
||||
/* a markup attribute value */
|
||||
.atv {
|
||||
color: #3e999f; }
|
||||
|
||||
/* a declaration */
|
||||
.dec {
|
||||
color: #f5871f; }
|
||||
|
||||
/* a variable name */
|
||||
.var {
|
||||
color: #c82829; }
|
||||
|
||||
/* a function name */
|
||||
.fun {
|
||||
color: #4271ae; } }
|
||||
/* Use higher contrast and text-weight for printable form. */
|
||||
@media print, projection {
|
||||
.str {
|
||||
color: #060; }
|
||||
|
||||
.kwd {
|
||||
color: #006;
|
||||
font-weight: bold; }
|
||||
|
||||
.com {
|
||||
color: #600;
|
||||
font-style: italic; }
|
||||
|
||||
.typ {
|
||||
color: #404;
|
||||
font-weight: bold; }
|
||||
|
||||
.lit {
|
||||
color: #044; }
|
||||
|
||||
.pun, .opn, .clo {
|
||||
color: #440; }
|
||||
|
||||
.tag {
|
||||
color: #006;
|
||||
font-weight: bold; }
|
||||
|
||||
.atn {
|
||||
color: #404; }
|
||||
|
||||
.atv {
|
||||
color: #060; } }
|
||||
/* Style */
|
||||
/*
|
||||
pre.prettyprint {
|
||||
background: white;
|
||||
font-family: Consolas, Monaco, 'Andale Mono', monospace;
|
||||
font-size: 12px;
|
||||
line-height: 1.5;
|
||||
border: 1px solid #ccc;
|
||||
padding: 10px; }
|
||||
*/
|
||||
|
||||
/* Specify class=linenums on a pre to get line numbering */
|
||||
ol.linenums {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0; }
|
||||
|
||||
/* IE indents via margin-left */
|
||||
li.L0,
|
||||
li.L1,
|
||||
li.L2,
|
||||
li.L3,
|
||||
li.L4,
|
||||
li.L5,
|
||||
li.L6,
|
||||
li.L7,
|
||||
li.L8,
|
||||
li.L9 {
|
||||
/* */ }
|
||||
|
||||
/* Alternate shading for lines */
|
||||
li.L1,
|
||||
li.L3,
|
||||
li.L5,
|
||||
li.L7,
|
||||
li.L9 {
|
||||
/* */ }
|
||||
Loading…
x
Reference in New Issue
Block a user