-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #97 from giftofgrub/checkPOIs
POI Manager
- Loading branch information
Showing
13 changed files
with
602 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
[ | ||
{ | ||
"type": "Feature", | ||
"geometry": { | ||
"type": "Point", | ||
"coordinates": [ | ||
"-121.80158876559241", | ||
"37.2992397" | ||
] | ||
}, | ||
"properties": { | ||
"title": "8 Minutes", | ||
"artist": "Merge Conceptual Design", | ||
"address": "1924 Yerba Buena Road", | ||
"city": "San Jose", | ||
"state": "CA", | ||
"postalCode": "95121", | ||
"image": "https://sanjoseca.gov/Home/ShowPublishedImage/4878/636714226994330000", | ||
"description": "The National Fire Protection Association recommends a target of 8 minutes as “standard response time” for emergency calls. The artwork 8 Minutes approaches the topic of the 8-minute response in three ways:\n\n A visual measurement of 8 minutes,\n A conveyor of Fire Station 24th continuous efforts on behalf of the community, and\n Connecting the community to the station via the eight minute duration.\n\nAll the elements complement each other to create a rich understanding of time in the context of Fire Station 24.\nThe first element is the LED Countdown Timer placed over the apparatus bay. The timer is connected to the fire pager system; when a response call is received it automatically starts an 8-minute counter that travels as a light across the sign. After the 8-minute light completes its travel across the sign, the \"call time\" is added to a list of the 8 most recent call times displayed on the sign. The second and third components of the artwork are a series of tiles in the fire station entryway. One set of tiles is a compilation of text about the number 8 and 8-minute duration. For example: “A fallen or lying down 8 is used to represent infinity in mathematics.” The third component is a series of 8-minute time-lapsed community photographs that depict every day activities to the same time frame of the recommended standard response time – to provide visitors to the station a visceral sense of the anxiety-filled 8 minutes awaiting emergency response versus the same 8-minutes washing a car, skateboarding or barbecuing.", | ||
"sourceURL": "https://sanjoseca.gov/Home/Components/FacilityDirectory/FacilityDirectory/2477/1396", | ||
"sourceOfInformation": "Created by POI Manager" | ||
}, | ||
"id": "art_fb3517580c972354c2b65afcba98c0aa0174184a4b77b1204b870e41046d1b05" | ||
} | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
mapboxgl.accessToken = "pk.eyJ1IjoieWNob3kiLCJhIjoiY2pmOTYwdzZ5MG52dDJ3b2JycXY4ZDU5ciJ9.m9H_Mqu1b42AObg_u_tjpA"; | ||
|
||
let map = new mapboxgl.Map({ | ||
container: "map", | ||
style: "mapbox://styles/mapbox/light-v9", | ||
center: [-121.893028, 37.33548], // position in long, lat format | ||
zoom: 10, | ||
dragPan: true, // If true , the "drag to pan" interaction is enabled (see DragPanHandler) | ||
trackResize: true, // If true, the map will automatically resize when the browser window resizes. | ||
doubleClickZoom: true, //If true double click will zoom | ||
keyboard: true //If true will enable keyboard shortcuts | ||
}); | ||
|
||
map.on("load", function(e) { | ||
let current = getCurrentVariables(); | ||
let {longitude, latitude, address, city, state, postalCode} = current; | ||
if (longitude && latitude) { | ||
// coordinates are present | ||
mapFlyToCurrent(); | ||
} else { | ||
// coordinates are not present. | ||
if (address && city && state && postalCode) { | ||
queryNominatim(); | ||
} else { | ||
console.log("artwork does not have coordinates or a valid address") | ||
} | ||
} | ||
}); | ||
|
||
function queryNominatim() { | ||
let current = getCurrentVariables(); | ||
const nominatimAPI = `https://nominatim.openstreetmap.org/?`; | ||
let query = { | ||
params:{ | ||
q: current.address + ", " + current.city + ", " + current.state + ", " + current.postalCode, | ||
format: "geocodejson", | ||
limit: "1", | ||
} | ||
} | ||
axios | ||
.get(nominatimAPI, query) | ||
.then( | ||
function(response) { | ||
let [long, lat] = response.data.features[0].geometry.coordinates; | ||
document.getElementById("longitude").value = long; | ||
document.getElementById("latitude").value = lat; | ||
mapFlyToCurrent(); | ||
}) | ||
.catch( | ||
function(error) { | ||
alert("Error getting coordinates from Nominatim.\nPlease make sure to have a legitimate address, city, and state.") | ||
}); | ||
} | ||
|
||
function submitPOI() { | ||
let current = getCurrentVariables(); | ||
let {title, artist, address, description, city, state, postalCode, image, sourceURL, id, latitude, longitude, pageType} = current; | ||
if (!current.latitude || !current.longitude) { | ||
alert("Missing Coordinates. Cannot Submit"); | ||
return | ||
} | ||
if (!title || !artist || !description ) { | ||
alert("Missing Details. Cannot Submit") | ||
return | ||
} | ||
|
||
let pathTo = "/POI"; | ||
if (pageType === "Edit") {pathTo = `/POI/${id}`} | ||
axios.post(pathTo, { | ||
title, artist, address, description, city, state, postalCode, image, sourceURL, id, latitude, longitude | ||
}) | ||
.then( response => { | ||
const statusCode = response.status; | ||
if (statusCode === 201) { | ||
console.log(response.data.artwork); | ||
alert( | ||
"successfully submitted artwork\n" + | ||
response.data.artwork.properties.title + | ||
"\nby\n" + | ||
response.data.artwork.properties.artist); | ||
} | ||
else { | ||
alert("Failed artwork creation") | ||
} | ||
window.location = ("/"); | ||
}).catch(error => { | ||
alert(error); | ||
window.location = ("/"); | ||
}) | ||
} | ||
|
||
var popup; | ||
|
||
function mapFlyToCurrent() { | ||
let current = getCurrentVariables(); | ||
let {longitude, latitude, title, artist, address, city, state, postalCode, image, description} = current; | ||
if (!latitude || !longitude) { alert("Unable to fly to artwork. Missing coordinates"); return } | ||
map.flyTo({ | ||
center: [longitude, latitude], | ||
zoom: 15 | ||
}); | ||
if (popup) {popup.remove()} | ||
popup = new mapboxgl.Popup({ closeOnClick: true, closeButton: true, anchor: "top" }) | ||
.setLngLat([longitude, latitude]) | ||
.setHTML( | ||
`<div style="width: 300px;"> | ||
<h3>${title}</h3> | ||
<p>by ${artist}</p> | ||
<p>Address: ${address}, ${city}, ${state}, ${postalCode}</p> | ||
<div> | ||
<img style="width: 300px" src=${image}> | ||
</div> | ||
<div><strong>Description: </strong><p>${description}</p></div> | ||
</div>` | ||
).addTo(map); | ||
} | ||
|
||
function getCurrentVariables() { | ||
let lib = { | ||
title: 'title', | ||
artist: 'artist', | ||
description: 'description', | ||
address: 'address', | ||
city: 'city', | ||
state: 'state', | ||
postalCode: 'postalCode', | ||
image: 'image', | ||
sourceURL: 'sourceURL', | ||
id: 'artworkId', | ||
latitude: 'latitude', | ||
longitude: 'longitude', | ||
}; | ||
// let title, artist, description, address, city, state, postalCode, image, sourceURL, id, longitude, latitude; | ||
Object.keys(lib).forEach( (key) => { | ||
lib[key] = document.getElementById(lib[key]).value; | ||
}) | ||
lib.pageType = document.getElementById("pageType").innerText; | ||
return lib; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
const { PATH_SCRAPED_ARTWORKS, PATH_MANAGED_POIs } = require('../../config/file-paths'); | ||
const fs = require('fs'); | ||
|
||
class POIManager { | ||
constructor(data) { | ||
this.scrapedArtworks = {}; | ||
this.managedArtworks = {}; | ||
} | ||
|
||
refreshArtworks() { | ||
const managedArr = require(PATH_MANAGED_POIs); | ||
const scrapedArr = require(PATH_SCRAPED_ARTWORKS); | ||
managedArr.forEach((artwork) => { | ||
this.managedArtworks[artwork.id] = artwork; | ||
}); | ||
scrapedArr.forEach( (artwork) => { | ||
if (!this.managedArtworks[artwork.id]) { | ||
this.scrapedArtworks[artwork.id] = artwork; | ||
} else if (this.managedArtworks[artwork.id]) { | ||
delete this.scrapedArtworks[artwork.id] | ||
} | ||
}); | ||
} | ||
|
||
writeArtworkToFile(artworkToSubmit) { | ||
this.managedArtworks[artworkToSubmit.id] = artworkToSubmit; | ||
const managedArtworksString = JSON.stringify(Object.values(this.managedArtworks), null, 2) | ||
return new Promise(resolve => { | ||
fs.writeFile(PATH_MANAGED_POIs, managedArtworksString, {flags: "r+"}, err => { | ||
if (err) { return reject(err) }; | ||
resolve(); | ||
}) | ||
}).catch(console.error); | ||
} | ||
} | ||
|
||
module.exports = POIManager; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<meta http-equiv="X-UA-Compatible" content="ie=edge"> | ||
<title>Document</title> | ||
|
||
<!-- Include style CSS and JavaScript --> | ||
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> | ||
<script | ||
src="https://code.jquery.com/jquery-3.3.1.min.js" | ||
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" | ||
crossorigin="anonymous"></script> | ||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script> | ||
</head> | ||
<body> | ||
|
||
<div class="container instructions-area w-100"> | ||
<h1>POIs Index</h1> | ||
<p>Please check details of each POI / Artwork. Use responsibly.</p> | ||
</div> | ||
|
||
<div class="container"> | ||
<div class="row"> | ||
<div class="col-md-6"> | ||
<h4>Scraped Artworks</h4> | ||
<ol class="scraped-artworks list-group"> | ||
<% scrapedArtworks.forEach((artwork) => { %> | ||
<li style="border: 1px solid gray; margin-bottom: 1px; padding-left: 2px;"> | ||
<a href=<%="/POI/" + artwork.id%> > | ||
<%= artwork.properties.title%> | ||
</a> | ||
</li> | ||
<% }) %> | ||
|
||
</ol> | ||
</div> | ||
<div class="col-md-6"> | ||
<div style="display: flex; justify-content: space-between;"> | ||
<h4 style="display:inline">Managed POIs</h4> | ||
<form action="/POI/new" method="get"> | ||
<button class="btn" style="border: 1px solid black; margin-left: 5px;">Create New POI</button> | ||
</form> | ||
</div> | ||
|
||
<ol class="scraped-artworks list-group"> | ||
<% managedArtworks.forEach((artwork) => { %> | ||
<li style="border: 1px solid gray; margin-bottom: 1px;"> | ||
<a href=<%="/POI/" + artwork.id%> > | ||
<%= artwork.properties.title%> | ||
</a> | ||
</li> | ||
<% }) %> | ||
|
||
</ol> | ||
</div> | ||
</div> | ||
</div> | ||
</body> | ||
|
||
</html> |
Oops, something went wrong.