Skip to content

Commit 3af4bb8

Browse files
committed
first commit
1 parent 1f39a60 commit 3af4bb8

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+4389
-0
lines changed

imgs/C3-BUILDING.jpg

246 KB

imgs/C3-SITE.jpg

269 KB

imgs/C4-BUILDING.jpg

254 KB

imgs/C4-SITE.jpg

270 KB

imgs/C5-BUILDING.jpg

258 KB

imgs/C5-SITE.jpg

270 KB

imgs/CV-BUILDING.jpg

214 KB

imgs/CV-SITE.jpg

251 KB

imgs/CX3-BUILDING.jpg

261 KB

imgs/CX3-SITE.jpg

267 KB

imgs/CX4-BUILDING.jpg

266 KB

imgs/CX4-SITE.jpg

266 KB

imgs/CX5-BUILDING.jpg

274 KB

imgs/CX5-SITE.jpg

267 KB

imgs/H3-BUILDING.jpg

252 KB

imgs/H3-SITE.jpg

292 KB

imgs/H4-BUILDING.jpg

250 KB

imgs/H4-SITE.jpg

293 KB

imgs/IX3-BUILDING.jpg

228 KB

imgs/IX3-SITE.jpg

257 KB

imgs/IX5-BUILDING.jpg

238 KB

imgs/IX5-SITE.jpg

258 KB

imgs/IX7-BUILDING.jpg

248 KB

imgs/IX7-SITE.jpg

256 KB

imgs/N2.5-BUILDING.jpg

264 KB

imgs/N2.5-SITE.jpg

304 KB

imgs/NX3-BUILDING.jpg

265 KB

imgs/NX3-SITE.jpg

304 KB

imgs/PK-BUILDING.jpg

198 KB

imgs/PK-SITE.jpg

250 KB

imgs/UI4-BUILDING.jpg

231 KB

imgs/UI4-SITE.jpg

261 KB

imgs/UIC-BUILDING.jpg

221 KB

imgs/UIC-SITE.jpg

261 KB

imgs/UN3-BUILDING.jpg

241 KB

imgs/UN3-SITE.jpg

255 KB

imgs/UN4-BUILDING.jpg

254 KB

imgs/UN4-SITE.jpg

255 KB

imgs/UN5-BUILDING.jpg

261 KB

imgs/UN5-SITE.jpg

254 KB

imgs/UX3-BUILDING.jpg

249 KB

imgs/UX3-SITE.jpg

258 KB

imgs/UX4-BUILDING.jpg

255 KB

imgs/UX4-SITE.jpg

257 KB

imgs/UX5-BUILDING.jpg

259 KB

imgs/UX5-SITE.jpg

257 KB

index.html

+279
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,279 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<base target="_top">
5+
<meta charset="utf-8">
6+
<meta name="viewport" content="width=device-width, initial-scale=1">
7+
8+
<title>CLE Form-Based Code</title>
9+
10+
<link rel="shortcut icon" type="image/x-icon" href="docs/images/favicon.ico" />
11+
<script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script>
12+
<script src="https://kit.fontawesome.com/a7ec421c16.js" crossorigin="anonymous"></script>
13+
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin=""/>
14+
<script src="https://unpkg.com/[email protected]/dist/leaflet.js" integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script>
15+
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
16+
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
17+
18+
<style>
19+
html, body {
20+
height: 100%;
21+
margin: 0;
22+
}
23+
.leaflet-container {
24+
height: 100%;
25+
width: 100%;
26+
max-width: 100%;
27+
max-height: 100%;
28+
}
29+
</style>
30+
31+
<style>#map { width: 100%; height: 100%; }
32+
.info { padding: 6px 8px; font: 14px/16px Arial, Helvetica, sans-serif; background: white; background: rgba(255,255,255,0.8); box-shadow: 0 0 15px rgba(0,0,0,0.2); border-radius: 5px; } .info h4 { margin: 0 0 5px; color: #777; }
33+
.legend { text-align: left; line-height: 18px; color: #555; } .legend i { width: 18px; height: 18px; float: left; margin-right: 8px; opacity: 0.7; }</style>
34+
</head>
35+
<body>
36+
<!-- Modal -->
37+
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
38+
<div class="modal-dialog modal-lg">
39+
<div class="modal-content">
40+
<div class="modal-header">
41+
<h4 class="modal-title" id="exampleModalLabel">Happy Election Day! &#127881;</h4>
42+
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
43+
</div>
44+
<div class="modal-body">
45+
<p>Thanks for visiting my map! This map uses <a href="https://updates.electionlink.net/widgets/cuyoh/2023-08-08/index.html" target="_blank">real-time voting data</a> shared online by the Cuyahoga Board of Elections.</p>
46+
<h5>New map features this Election:</h5>
47+
<p><div class="progress" style="height:1rem"><div class="progress-bar bg-info" id="timerSample" role="progressbar" style="width:100%" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100"><span style="color:#000">Automatic 60sec refresh</span></div></div>
48+
</p>
49+
<p>New map legend colors <span style="color:#FAFAFA">&#9632;</span><span style="color:#E3E3F0">&#9632;</span><span style="color:#C7C7E2">&#9632;</span><span style="color:#ACACD4">&#9632;</span><span style="color:#9090C6">&#9632;</span><span style="color:#7474B8">&#9632;</span><span style="color:#5959AA">&#9632;</span><span style="color:#3D3D9C">&#9632;</span><span style="color:#21218E">&#9632;</span><span style="color:#060680">&#9632;</span></p>
50+
<p>Full-screen mode <i class="fas fa-expand"></i> button for watching all day on larger screens</p>
51+
<p>Precinct/ward toggle <i class="fas fa-sliders-h"></i> button (Cleveland wards only, sorry)</p>
52+
53+
<p>For prior elections, the map illustrated voter turnout %s. I've switched to vote totals for this Election, but you'll still find the turnout %s in the infobox!</p>
54+
<h5>Good luck to all campaigns!</h5>
55+
<p><em>-Angelo <a href="https://twitter.com/trivisonno" target="_blank">@Trivisonno <i class="fab fa-twitter"></i></a></em></p>
56+
</div>
57+
<div class="modal-footer">
58+
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
59+
</div>
60+
</div>
61+
</div>
62+
</div>
63+
</div>
64+
65+
<div id='map'></div>
66+
67+
<script type="text/javascript" src="js/fbc.js"></script>
68+
<script type="text/javascript" src="js/permitted-use-table-by-zone.js"></script>
69+
70+
<script type="text/javascript">
71+
72+
const exampleModal = document.getElementById('exampleModal')
73+
var myModal = new bootstrap.Modal(exampleModal, {
74+
keyboard: false
75+
})
76+
77+
78+
79+
80+
const colors = {
81+
'C3': {'color': 'f1dbda', 'name': 'C3 Community 3'},
82+
'C4': {'color': 'c4a4a6', 'name': 'C4 Community 4'},
83+
'CV': {'color': 'adafaf', 'name': 'CV Civic'},
84+
'CX3': {'color': 'dbb2b1', 'name': 'CX3 Community Flex 3'},
85+
'CX4': {'color': 'be7268', 'name': 'CX4 Community Flex 4'},
86+
'H3': {'color': 'fef5c4', 'name': 'H3 House 3'},
87+
'H4': {'color': 'fbe78b', 'name': 'H4 House 4'},
88+
'IX3': {'color': 'b8acb8', 'name': 'IX3 Industrial Flex 3'},
89+
'IX5': {'color': '7e7794', 'name': 'IX5 Industrial Flex 5'},
90+
'IX7': {'color': '7e7794', 'name': 'IX7 Industrial Flex 7'},
91+
'N2.5': {'color': 'f0ca81', 'name': 'N2.5 Neighorhood 2.5'},
92+
'NX3': {'color': 'e1a14b', 'name': 'NX3 Neighborhood Flex 3'},
93+
'PK': {'color': 'abb687', 'name': 'PK Park'},
94+
'UI4': {'color': 'e5ced3', 'name': 'UI4 Urban Innovation 4'},
95+
'UIC': {'color': 'c498a8', 'name': 'UIC Urban Innovation Campus'},
96+
'UN3': {'color': 'a6c3c0', 'name': 'UN3 Urban Node 3'},
97+
'UN4': {'color': '619290', 'name': 'UN4 Urban Node 4'},
98+
'UN5': {'color': '3f6b68', 'name': 'UN5 Urban Node 5'},
99+
'UX3': {'color': 'cfdce4', 'name': 'UX3 Urban Flex 3'},
100+
'UX4': {'color': 'afbcc2', 'name': 'UX4 Urban Flex 4'},
101+
'UX5': {'color': '6f809a', 'name': 'UX5 Urban Flex 5'}
102+
}
103+
const map = L.map('map').setView([41.505493, -81.681290], 13);
104+
105+
const tiles = L.tileLayer('https://tiles.stadiamaps.com/tiles/alidade_smooth/{z}/{x}/{y}{r}.{ext}', {
106+
minZoom: 0,
107+
maxZoom: 20,
108+
attribution: '&copy; <a href="https://www.stadiamaps.com/" target="_blank">Stadia Maps</a> &copy; <a href="https://openmaptiles.org/" target="_blank">OpenMapTiles</a> &copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
109+
ext: 'png'}).addTo(map);
110+
111+
// control that shows state info on hover
112+
const info = L.control();
113+
114+
info.onAdd = function (map) {
115+
this._div = L.DomUtil.create('div', 'info');
116+
this.update();
117+
return this._div;
118+
};
119+
120+
info.update = function (props) {
121+
const contents = props ? `<b>Parcel PIN: ${props.parcelpin}</b><br />Zoning District: ${colors[props.fbc_zoning]['name']}` : 'Hover over a parcel';
122+
this._div.innerHTML = `<h4>Cleveland's Form-Based Zoning Code</h4>${contents}`;
123+
};
124+
125+
// info.addTo(map);
126+
127+
128+
// get color depending on population density value
129+
function getColor(d) {
130+
// console.log(d)
131+
return '#'+colors[d]['color'];
132+
return d > 1000 ? '#800026' :
133+
d > 500 ? '#BD0026' :
134+
d > 200 ? '#E31A1C' :
135+
d > 100 ? '#FC4E2A' :
136+
d > 50 ? '#FD8D3C' :
137+
d > 20 ? '#FEB24C' :
138+
d > 10 ? '#FED976' : '#FFEDA0';
139+
}
140+
141+
function style(feature) {
142+
return {
143+
weight: 1,
144+
opacity: 1,
145+
color: 'gray',
146+
dashArray: '3',
147+
fillOpacity: 0.7,
148+
fillColor: getColor(feature.properties.fbc_zoning)
149+
};
150+
}
151+
152+
function highlightFeature(e) {
153+
const layer = e.target;
154+
155+
layer.setStyle({
156+
weight: 5,
157+
color: '#666',
158+
dashArray: '',
159+
fillOpacity: 0.7
160+
});
161+
162+
layer.bringToFront();
163+
164+
info.update(layer.feature.properties);
165+
}
166+
167+
/* global statesData */
168+
const geojson = L.geoJson(fbc, {
169+
style,
170+
onEachFeature
171+
}).addTo(map);
172+
173+
function resetHighlight(e) {
174+
geojson.resetStyle(e.target);
175+
info.update();
176+
}
177+
178+
function updateModal(zoning, parcelpin) {
179+
$('#exampleModalLabel').html("Zoning:" + colors[zoning]['name']);
180+
181+
popup_data = '<h2>Parcel '+parcelpin+' <a target="_blank" href="http://neocando.case.edu/cando/propLaunch.jsp?type=aud&parcel='+parcelpin+'"><i class="fa-solid fa-link"></i></a></h2><br><div style="overflow:hidden;overflow-y:scroll;"><b>Property Uses:</b><br><table class="table table-striped"><tr>';
182+
183+
for (const [key, value] of Object.entries(permitted_uses_by_zone[zoning])) {
184+
if (value == 'P') {
185+
text_value = '<i class="fa-regular fa-circle-check"></i></td><td>(P) Permitted'
186+
} else if (value == 'C') {
187+
text_value = '<i class="fa-solid fa-triangle-exclamation"></i></td><td>(C) Conditional,<br>CPC approval req.'
188+
} else if (value == 'P*') {
189+
text_value = '<i class="fa-regular fa-circle-check"></i></td><td>(P*) Permitted,<br>w/additional use standards'
190+
} else if (value == 'C*') {
191+
text_value = '<i class="fa-solid fa-triangle-exclamation"></i></td><td>(C*) Conditional,<br>CPC approval req.<br>w/additional use standards'
192+
} else if (value == 'NP') {
193+
text_value = '<i class="fa-solid fa-square-xmark"></i></td><td>Variance required'
194+
}
195+
popup_data += `<td>${key}</td><td> ${text_value}</td></tr>`;
196+
}
197+
popup_data += "</table>";
198+
popup_data += '<img width=100% src="imgs/'+zoning + '-SITE.jpg"><br><img width=100% src="imgs/'+zoning + '-BUILDING.jpg"></div>';
199+
200+
$('.modal-body').html(popup_data)
201+
}
202+
203+
function openThePopup(e) {
204+
updateModal(e.target.feature.properties.fbc_zoning, e.target.feature.properties.parcelpin)
205+
myModal.show()
206+
}
207+
208+
function onEachFeature(feature, layer) {
209+
layer.on({
210+
mouseover: highlightFeature,
211+
mouseout: resetHighlight,
212+
click: openThePopup
213+
});
214+
215+
// popup_data = '<h2>Parcel '+feature.properties.parcelpin+' <a target="_blank" href="http://neocando.case.edu/cando/propLaunch.jsp?type=aud&parcel='+feature.properties.parcelpin+'"><i class="fa-solid fa-link"></i></a></h2><h3>Zoning: '+colors[feature.properties.fbc_zoning]['name']+'</h3><div style="height:100px;overflow:hidden;overflow-y:scroll;"><b>Property Uses:</b><br><table class="table table-striped">';
216+
217+
// for (const [key, value] of Object.entries(permitted_uses_by_zone[feature.properties.fbc_zoning])) {
218+
// if (value == 'P') {
219+
// text_value = '<i class="fa-regular fa-circle-check"></i></td><td>OK'
220+
// } else if (value == 'C') {
221+
// text_value = '<i class="fa-solid fa-triangle-exclamation"></i></td><td>Conditional, CPC approval req.'
222+
// } else if (value == 'P*') {
223+
// text_value = '<i class="fa-regular fa-circle-check"></i></td><td>OK, w/rules'
224+
// } else if (value == 'C*') {
225+
// text_value = '<i class="fa-solid fa-triangle-exclamation"></i></td><td>Conditional, CPC approval req. & w/rules'
226+
// } else if (value == 'NP') {
227+
// text_value = '<i class="fa-solid fa-square-xmark"></i></td><td>Variance req.'
228+
// }
229+
// popup_data += `<td>${key}</td><td> ${text_value}</td>`;
230+
// }
231+
// popup_data += "</table>";
232+
// popup_data += '<img width=200 src="imgs/'+feature.properties.fbc_zoning + '-SITE.jpg"><br><img width=200 src="imgs/'+feature.properties.fbc_zoning + '-BUILDING.jpg"></div>';
233+
234+
// layer.bindPopup(popup_data, {
235+
// maxWidth : 560
236+
// });
237+
238+
239+
240+
241+
242+
}
243+
244+
245+
246+
const legend = L.control({position: 'bottomright'});
247+
248+
legend.onAdd = function (map) {
249+
250+
const div = L.DomUtil.create('div', 'info legend');
251+
const grades = [0, 10, 20, 50, 100, 200, 500, 1000];
252+
const labels = [];
253+
const zones = ['C3', 'C4', 'CV', 'CX3', 'CX4']
254+
255+
let from, to;
256+
257+
// for (let i = 0; i < zones.length; i++) {
258+
// // from = grades[i];
259+
// // to = grades[i + 1];
260+
261+
// labels.push(`<i style="background:#${colors[zones[i]]}"></i> ${zones[i]}`);
262+
// }
263+
264+
for (const [key, value] of Object.entries(colors)) {
265+
labels.push(`<i style="background:#${value['color']}"></i> ${value['name']}`);
266+
}
267+
268+
div.innerHTML = labels.join('<br>');
269+
return div;
270+
};
271+
272+
// legend.addTo(map);
273+
274+
</script>
275+
276+
277+
278+
</body>
279+
</html>

0 commit comments

Comments
 (0)