277 lines
7.7 KiB
HTML
277 lines
7.7 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<title>JSDoc: Source: main.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: main.js</h1>
|
|
|
|
<section>
|
|
<article>
|
|
<pre class="prettyprint source linenums"><code>import "./style.css";
|
|
|
|
import { Map, View, Overlay } from "ol";
|
|
|
|
import { Tile as TileLayer, Vector as VectorLayer } from "ol/layer";
|
|
import { TileJSON, Vector as VectorSource } from "ol/source";
|
|
import { useGeographic } from "ol/proj.js";
|
|
import { defaults as defaultControls } from "ol/control.js";
|
|
|
|
import { Popover } from "bootstrap";
|
|
|
|
import searchBar from "./modules/searchBar.js";
|
|
import fetchPins from "./modules/fetchPins.js";
|
|
import ButtonControl from "./modules/newButton.js";
|
|
import changeResolutionHandler from "./modules/changeResolutionHandler.js";
|
|
import pointerMoveHandler from "./modules/pointerMoveHandler.js";
|
|
import searchInputHander from "./modules/searchInputHandler.js";
|
|
|
|
///
|
|
|
|
const search = searchBar;
|
|
|
|
let pinning = false;
|
|
|
|
let popover;
|
|
|
|
/** Vector source for pins
|
|
* @constant {ol.source.VectorSource} */
|
|
const pinSource = new VectorSource();
|
|
/** Vector layer for pin vector source
|
|
* @constant {ol.layer.VectorLayer} */
|
|
const pinLayer = new VectorLayer({
|
|
source: pinSource,
|
|
});
|
|
|
|
useGeographic();
|
|
|
|
fetchPins(pinSource);
|
|
|
|
/** Main map
|
|
* @constant {ol.Map} */
|
|
const map = new Map({
|
|
controls: defaultControls().extend([new ButtonControl()]),
|
|
target: document.getElementById("map"),
|
|
layers: [
|
|
new TileLayer({
|
|
source: new TileJSON({
|
|
url: `https://api.maptiler.com/maps/hybrid/tiles.json?key=${
|
|
import.meta.env.VITE_MAPTILER_KEY
|
|
}`,
|
|
tileSize: 512,
|
|
crossOrigin: "anonymous",
|
|
}),
|
|
}),
|
|
],
|
|
view: new View({
|
|
center: [0, 0],
|
|
zoom: 2,
|
|
maxZoom: 20,
|
|
}),
|
|
});
|
|
|
|
/** Overlay element for pin popups
|
|
* @constant {ol.Overlay} */
|
|
const popup = new Overlay({
|
|
element: document.getElementById("popup"),
|
|
positioning: "bottom-center",
|
|
stopEvent: false,
|
|
});
|
|
|
|
map.addOverlay(popup);
|
|
|
|
map.addControl(search);
|
|
|
|
const searchInput = search.getInputField();
|
|
searchInput.onkeydown = (event) => {
|
|
searchInputHander(event, map);
|
|
};
|
|
|
|
/** Removes store information popup from screen
|
|
*/
|
|
const disposePopover = () => {
|
|
if (popover) {
|
|
popover.dispose();
|
|
popover = undefined;
|
|
}
|
|
};
|
|
|
|
/** Handles user clicks. If user clicks on a pixel that contains a pin, display popup with store information
|
|
* @param {Event} event - User click event
|
|
* @param {bootstrap.Popover} popover - Popover object from Bootstrap/Popper
|
|
* @param {ol.Overlay} popup - Overlay element for pin popups
|
|
* @param {ol.Map} map - OpenLayers map
|
|
*/
|
|
|
|
map.on("click", (event) => {
|
|
disposePopover();
|
|
|
|
const feature = map.forEachFeatureAtPixel(event.pixel, (feature) => feature);
|
|
if (!feature) return;
|
|
|
|
popup.setPosition(event.coordinate);
|
|
|
|
const element = document.querySelector("#popup");
|
|
|
|
popover = new Popover(element, {
|
|
placement: "top",
|
|
html: true,
|
|
title: feature.get("store"),
|
|
content: function () {
|
|
const container = document.createElement("div");
|
|
|
|
const cheapestItem = document.createElement("div");
|
|
cheapestItem.textContent = `Cheapest Item: ${feature.get(
|
|
"cheapestItem"
|
|
)}`;
|
|
container.appendChild(cheapestItem);
|
|
|
|
const cheapestPerFloz = document.createElement("div");
|
|
cheapestPerFloz.textContent = `$ / oz.: ${feature.get("pricePerOz")}`;
|
|
container.appendChild(cheapestPerFloz);
|
|
|
|
const link = document.createElement("a");
|
|
link.href = "#";
|
|
link.onclick = function (event) {
|
|
event.preventDefault();
|
|
window.ReactNativeWebView?.postMessage(
|
|
`open@${feature.getGeometry().getCoordinates()}`
|
|
);
|
|
};
|
|
link.textContent = "More...";
|
|
container.appendChild(link);
|
|
|
|
return container;
|
|
},
|
|
});
|
|
|
|
popover.show();
|
|
});
|
|
|
|
map.on("pointermove", (event) => {
|
|
pointerMoveHandler(event, map);
|
|
});
|
|
|
|
map.on("movestart", disposePopover);
|
|
|
|
map.getView().on("change:resolution", () => {
|
|
changeResolutionHandler(pinning, map, pinLayer);
|
|
});
|
|
|
|
/** Centers location on user based on location information passed in from expo-location
|
|
* @param {number} lon - User's longitude
|
|
* @param {number} lat - User's latitude
|
|
*/
|
|
window.passLocation = (lon, lat) => {
|
|
const view = new View({
|
|
center: [lon, lat],
|
|
zoom: 18,
|
|
maxZoom: 20,
|
|
});
|
|
|
|
map.setView(view);
|
|
map.getLayers().extend([pinLayer]);
|
|
|
|
// sets NEW listener to listen for zoom changes
|
|
view.on("change:resolution", () => {
|
|
view.getZoom() < 5
|
|
? map.getLayers().removeAt(1)
|
|
: (() => {
|
|
if (map.getLayers().getLength() === 1) {
|
|
if (!pinning) map.getLayers().extend([pinLayer]);
|
|
}
|
|
})();
|
|
});
|
|
};
|
|
|
|
/** Begins store creation process if user clicks on "New" button
|
|
*/
|
|
window.placePin = () => {
|
|
button.removeEventListener("click", newButtonHandler, false);
|
|
pinning = true;
|
|
map.getLayers().removeAt(1);
|
|
// adds pin in center of view
|
|
document.getElementById("centerPin").style.display = "block";
|
|
// changes new button to OK button
|
|
button.textContent = "OK";
|
|
// OK button has event listener that on click
|
|
function OKButtonHandler() {
|
|
// removes listener on button in case someone wants to mash it
|
|
button.removeEventListener("click", OKButtonHandler, false);
|
|
// removes pin in center of view
|
|
document.getElementById("centerPin").style.display = "none";
|
|
// emits to RN
|
|
window.ReactNativeWebView?.postMessage(
|
|
`create@${map.getView().getCenter()}`
|
|
);
|
|
}
|
|
button.addEventListener("click", OKButtonHandler, false);
|
|
};
|
|
</code></pre>
|
|
</article>
|
|
</section>
|
|
</div>
|
|
|
|
<nav>
|
|
<h2><a href="index.html">Home</a></h2>
|
|
<h3>Modules</h3>
|
|
<ul>
|
|
<li>
|
|
<a href="module-changeResolutionHandler.html"
|
|
>changeResolutionHandler</a
|
|
>
|
|
</li>
|
|
<li><a href="module-fetchPins.html">fetchPins</a></li>
|
|
<li><a href="module-makePin.html">makePin</a></li>
|
|
<li><a href="module-newButton.html">newButton</a></li>
|
|
<li><a href="module-pointerMoveHandler.html">pointerMoveHandler</a></li>
|
|
<li><a href="module-searchBar.html">searchBar</a></li>
|
|
<li><a href="module-searchInputHander.html">searchInputHander</a></li>
|
|
<li><a href="module-toLatLon.html">toLatLon</a></li>
|
|
</ul>
|
|
<h3>Classes</h3>
|
|
<ul>
|
|
<li><a href="module-newButton-ButtonControl.html">ButtonControl</a></li>
|
|
</ul>
|
|
<h3>Global</h3>
|
|
<ul>
|
|
<li><a href="global.html#disposePopover">disposePopover</a></li>
|
|
<li><a href="global.html#map-onclick">map.onclick</a></li>
|
|
<li><a href="global.html#passlocation">window.passLocation</a></li>
|
|
<li><a href="global.html#placepin">window.placePin</a></li>
|
|
<li><a href="global.html#map">map</a></li>
|
|
<li><a href="global.html#pinLayer">pinLayer</a></li>
|
|
<li><a href="global.html#pinSource">pinSource</a></li>
|
|
<li><a href="global.html#popup">popup</a></li>
|
|
</ul>
|
|
</nav>
|
|
|
|
<br class="clear" />
|
|
|
|
<footer>
|
|
Documentation generated by
|
|
<a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a> on Sun Dec 31
|
|
2023 15:19:11 GMT-0800 (Pacific Standard Time)
|
|
</footer>
|
|
|
|
<script>
|
|
prettyPrint();
|
|
</script>
|
|
<script src="scripts/linenumber.js"></script>
|
|
</body>
|
|
</html>
|