web-mapping 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/_includes/about.html +0 -0
- data/_includes/contact.html +0 -0
- data/_includes/google-analytics.html +9 -0
- data/_includes/head.html +36 -0
- data/_includes/leafletmap.html +225 -0
- data/_includes/navbar.html +41 -0
- data/assets/css/main.scss +1 -0
- data/assets/img/favicon-120.png +0 -0
- data/assets/img/favicon-152.png +0 -0
- data/assets/img/favicon-196.png +0 -0
- data/assets/img/favicon-76.png +0 -0
- data/assets/img/favicon.ico +0 -0
- data/assets/img/globe.png +0 -0
- data/assets/img/museum.png +0 -0
- data/assets/img/theater.png +0 -0
- data/assets/js/app.js +606 -0
- data/assets/leaflet-groupedlayercontrol/MIT-LICENSE.txt +20 -0
- data/assets/leaflet-groupedlayercontrol/leaflet.groupedlayercontrol.css +13 -0
- data/assets/leaflet-groupedlayercontrol/leaflet.groupedlayercontrol.js +291 -0
- data/assets/main.css +178 -0
- data/index.md +3 -0
- metadata +22 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9ce5618fed49008ac82cd161ddb1d56ff047ea152c350a3e6439cd921ce792ce
|
|
4
|
+
data.tar.gz: 92d35b9454e710c9390248b0718f13412d39d313614398f4ed0c6289a1cc86ef
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c9c88a59afbf4fa85a55a517cf359eccc9451c16e540b2a95a23dd85ee785f447a888e2b802769c879c7b95865476587c11d2e5cae75fc8a6d54ebd3cb45a54f
|
|
7
|
+
data.tar.gz: 6973a77c615096e83c91e18d73bd486564d6d5d1ea6b75cbfe95abc582c556e7ba4112793a447afe30ae8ce1bc6c8276d46d415fa1d0debb402926fb4bc83bad
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<!-- Global site tag (gtag.js) - Google Analytics -->
|
|
2
|
+
<script async src="https://www.googletagmanager.com/gtag/js?id={{ site.google_analytics }}"></script>
|
|
3
|
+
<script>
|
|
4
|
+
window.dataLayer = window.dataLayer || [];
|
|
5
|
+
function gtag(){dataLayer.push(arguments);}
|
|
6
|
+
gtag('js', new Date());
|
|
7
|
+
|
|
8
|
+
gtag('config', '{{ site.google_analytics }}');
|
|
9
|
+
</script>
|
data/_includes/head.html
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
<head prefix="og: http://ogp.me/ns#">
|
|
2
|
+
<meta charset="utf-8">
|
|
3
|
+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
4
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
5
|
+
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
|
|
6
|
+
<meta name="HandheldFriendly" content="True">
|
|
7
|
+
<meta name="MobileOptimized" content="320">
|
|
8
|
+
<meta name="Robots" content="index, follow">
|
|
9
|
+
|
|
10
|
+
<!-- - -->
|
|
11
|
+
{%- seo -%}
|
|
12
|
+
<!-- - -->
|
|
13
|
+
|
|
14
|
+
<!-- CSS -->
|
|
15
|
+
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
|
|
16
|
+
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">
|
|
17
|
+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/leaflet.css">
|
|
18
|
+
<link rel="stylesheet" href="https://api.tiles.mapbox.com/mapbox.js/plugins/leaflet-markercluster/v0.4.0/MarkerCluster.css">
|
|
19
|
+
<link rel="stylesheet" href="https://api.tiles.mapbox.com/mapbox.js/plugins/leaflet-markercluster/v0.4.0/MarkerCluster.Default.css">
|
|
20
|
+
<link rel="stylesheet" href="https://api.tiles.mapbox.com/mapbox.js/plugins/leaflet-locatecontrol/v0.43.0/L.Control.Locate.css">
|
|
21
|
+
<link rel="stylesheet" href="assets/leaflet-groupedlayercontrol/leaflet.groupedlayercontrol.css">
|
|
22
|
+
<link rel="stylesheet" href="{{ '/assets/main.css' | prepend: site.url }}">
|
|
23
|
+
<!-- <link rel="stylesheet" href="assets/css/main.css"> -->
|
|
24
|
+
<link rel="apple-touch-icon" sizes="76x76" href="assets/img/favicon-76.png">
|
|
25
|
+
<link rel="apple-touch-icon" sizes="120x120" href="assets/img/favicon-120.png">
|
|
26
|
+
<link rel="apple-touch-icon" sizes="152x152" href="assets/img/favicon-152.png">
|
|
27
|
+
<link rel="icon" sizes="196x196" href="assets/img/favicon-196.png">
|
|
28
|
+
<link rel="icon" type="image/x-icon" href="assets/img/favicon.ico">
|
|
29
|
+
|
|
30
|
+
<!-- JS -->
|
|
31
|
+
<script src="{{ '/assets/js/app.js' | prepend: site.url }}"></script>
|
|
32
|
+
<!-- <script src="assets/js/app.js"></script> -->
|
|
33
|
+
{%- if jekyll.environment == 'production' and site.google_analytics -%}
|
|
34
|
+
{%- include google-analytics.html -%}
|
|
35
|
+
{%- endif -%}
|
|
36
|
+
</head>
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
<div id="container">
|
|
2
|
+
<div id="sidebar">
|
|
3
|
+
<div class="sidebar-wrapper">
|
|
4
|
+
<div class="panel panel-default" id="features">
|
|
5
|
+
<div class="panel-heading">
|
|
6
|
+
<h3 class="panel-title">Points of Interest
|
|
7
|
+
<button type="button" class="btn btn-xs btn-default pull-right" id="sidebar-hide-btn"><i class="fa fa-chevron-left"></i></button></h3>
|
|
8
|
+
</div>
|
|
9
|
+
<div class="panel-body">
|
|
10
|
+
<div class="row">
|
|
11
|
+
<div class="col-xs-8 col-md-8">
|
|
12
|
+
<input type="text" class="form-control search" placeholder="Filter" />
|
|
13
|
+
</div>
|
|
14
|
+
<div class="col-xs-4 col-md-4">
|
|
15
|
+
<button type="button" class="btn btn-primary pull-right sort" data-sort="feature-name" id="sort-btn"><i class="fa fa-sort"></i> Sort</button>
|
|
16
|
+
</div>
|
|
17
|
+
</div>
|
|
18
|
+
</div>
|
|
19
|
+
<div class="sidebar-table">
|
|
20
|
+
<table class="table table-hover" id="feature-list">
|
|
21
|
+
<thead class="hidden">
|
|
22
|
+
<tr>
|
|
23
|
+
<th>Icon</th>
|
|
24
|
+
<tr>
|
|
25
|
+
<tr>
|
|
26
|
+
<th>Name</th>
|
|
27
|
+
<tr>
|
|
28
|
+
<tr>
|
|
29
|
+
<th>Chevron</th>
|
|
30
|
+
<tr>
|
|
31
|
+
</thead>
|
|
32
|
+
<tbody class="list"></tbody>
|
|
33
|
+
</table>
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
</div>
|
|
37
|
+
</div>
|
|
38
|
+
<div id="map"></div>
|
|
39
|
+
</div>
|
|
40
|
+
<div id="loading">
|
|
41
|
+
<div class="loading-indicator">
|
|
42
|
+
<div class="progress progress-striped active">
|
|
43
|
+
<div class="progress-bar progress-bar-info progress-bar-full"></div>
|
|
44
|
+
</div>
|
|
45
|
+
</div>
|
|
46
|
+
</div>
|
|
47
|
+
<div class="modal fade" id="aboutModal" tabindex="-1" role="dialog">
|
|
48
|
+
<div class="modal-dialog modal-lg">
|
|
49
|
+
<div class="modal-content">
|
|
50
|
+
<div class="modal-header">
|
|
51
|
+
<button class="close" type="button" data-dismiss="modal" aria-hidden="true">×</button>
|
|
52
|
+
<h4 class="modal-title">Welcome to the BootLeaf template!</h4>
|
|
53
|
+
</div>
|
|
54
|
+
<div class="modal-body">
|
|
55
|
+
<ul class="nav nav-tabs nav-justified" id="aboutTabs">
|
|
56
|
+
<li class="active"><a href="#about" data-toggle="tab"><i class="fa fa-question-circle"></i> About the project</a></li>
|
|
57
|
+
<li><a href="#contact" data-toggle="tab"><i class="fa fa-envelope"></i> Contact us</a></li>
|
|
58
|
+
<li><a href="#disclaimer" data-toggle="tab"><i class="fa fa-exclamation-circle"></i> Disclaimer</a></li>
|
|
59
|
+
<li class="dropdown">
|
|
60
|
+
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><i class="fa fa-globe"></i> Metadata <b class="caret"></b></a>
|
|
61
|
+
<ul class="dropdown-menu">
|
|
62
|
+
<li><a href="#boroughs-tab" data-toggle="tab">Boroughs</a></li>
|
|
63
|
+
<li><a href="#subway-lines-tab" data-toggle="tab">Subway Lines</a></li>
|
|
64
|
+
<li><a href="#theaters-tab" data-toggle="tab">Theaters</a></li>
|
|
65
|
+
<li><a href="#museums-tab" data-toggle="tab">Museums</a></li>
|
|
66
|
+
</ul>
|
|
67
|
+
</li>
|
|
68
|
+
</ul>
|
|
69
|
+
<div class="tab-content" id="aboutTabsContent">
|
|
70
|
+
<div class="tab-pane fade active in" id="about">
|
|
71
|
+
<p>A simple, responsive template for building web mapping applications with <a href="http://getbootstrap.com/">Bootstrap 3</a>, <a href="http://leafletjs.com/" target="_blank">Leaflet</a>, and <a href="http://twitter.github.io/typeahead.js/" target="_blank">typeahead.js</a>. Open source, MIT licensed, and available on <a href="https://github.com/bmcbride/bootleaf" target="_blank">GitHub</a>.</p>
|
|
72
|
+
<div class="panel panel-primary">
|
|
73
|
+
<div class="panel-heading">Features</div>
|
|
74
|
+
<ul class="list-group">
|
|
75
|
+
<li class="list-group-item">Fullscreen mobile-friendly map template with responsive navbar and modal placeholders</li>
|
|
76
|
+
<li class="list-group-item">jQuery loading of external GeoJSON files</li>
|
|
77
|
+
<li class="list-group-item">Logical multiple layer marker clustering via the <a href="https://github.com/Leaflet/Leaflet.markercluster" target="_blank">leaflet marker cluster plugin</a></li>
|
|
78
|
+
<li class="list-group-item">Elegant client-side multi-layer feature search with autocomplete using <a href="http://twitter.github.io/typeahead.js/" target="_blank">typeahead.js</a></li>
|
|
79
|
+
<li class="list-group-item">Responsive sidebar feature list synced with map bounds, which includes sorting and filtering via <a href="http://listjs.com/" target="_blank">list.js</a></li>
|
|
80
|
+
<li class="list-group-item">Marker icons included in grouped layer control via the <a href="https://github.com/ismyrnow/Leaflet.groupedlayercontrol" target="_blank">grouped layer control plugin</a></li>
|
|
81
|
+
</ul>
|
|
82
|
+
</div>
|
|
83
|
+
</div>
|
|
84
|
+
<div id="disclaimer" class="tab-pane fade text-danger">
|
|
85
|
+
<p>The data provided on this site is for informational and planning purposes only.</p>
|
|
86
|
+
<p>Absolutely no accuracy or completeness guarantee is implied or intended. All information on this map is subject to such variations and corrections as might result from a complete title search and/or accurate field survey.</p>
|
|
87
|
+
</div>
|
|
88
|
+
<div class="tab-pane fade" id="contact">
|
|
89
|
+
<form id="contact-form">
|
|
90
|
+
<div class="well well-sm">
|
|
91
|
+
<div class="row">
|
|
92
|
+
<div class="col-md-4">
|
|
93
|
+
<div class="form-group">
|
|
94
|
+
<label for="first-name">First Name:</label>
|
|
95
|
+
<input type="text" class="form-control" id="first-name">
|
|
96
|
+
</div>
|
|
97
|
+
<div class="form-group">
|
|
98
|
+
<label for="last-name">Last Name:</label>
|
|
99
|
+
<input type="text" class="form-control" id="last-email">
|
|
100
|
+
</div>
|
|
101
|
+
<div class="form-group">
|
|
102
|
+
<label for="email">Email:</label>
|
|
103
|
+
<input type="text" class="form-control" id="email">
|
|
104
|
+
</div>
|
|
105
|
+
</div>
|
|
106
|
+
<div class="col-md-8">
|
|
107
|
+
<label for="message">Message:</label>
|
|
108
|
+
<textarea class="form-control" rows="8" id="message"></textarea>
|
|
109
|
+
</div>
|
|
110
|
+
<div class="col-md-12">
|
|
111
|
+
<p>
|
|
112
|
+
<button type="submit" class="btn btn-primary pull-right" data-dismiss="modal">Submit</button>
|
|
113
|
+
</p>
|
|
114
|
+
</div>
|
|
115
|
+
</div>
|
|
116
|
+
</div>
|
|
117
|
+
</form>
|
|
118
|
+
</div>
|
|
119
|
+
<div class="tab-pane fade" id="boroughs-tab">
|
|
120
|
+
<p>Borough data courtesy of <a href="http://www.nyc.gov/html/dcp/pdf/bytes/nybbwi_metadata.pdf" target="_blank">New York City Department of City Planning</a></p>
|
|
121
|
+
</div>
|
|
122
|
+
<div class="tab-pane fade" id="subway-lines-tab">
|
|
123
|
+
<p><a href="http://spatialityblog.com/2010/07/08/mta-gis-data-update/#datalinks" target="_blank">MTA Subway data</a> courtesy of the <a href="http://www.urbanresearch.org/about/cur-components/cuny-mapping-service" target="_blank">CUNY Mapping Service at the Center for Urban Research</a></p>
|
|
124
|
+
</div>
|
|
125
|
+
<div class="tab-pane fade" id="theaters-tab">
|
|
126
|
+
<p>Theater data courtesy of <a href="https://data.cityofnewyork.us/Recreation/Theaters/kdu2-865w" target="_blank">NYC Department of Information & Telecommunications (DoITT)</a></p>
|
|
127
|
+
</div>
|
|
128
|
+
<div class="tab-pane fade" id="museums-tab">
|
|
129
|
+
<p>Museum data courtesy of <a href="https://data.cityofnewyork.us/Recreation/Museums-and-Galleries/sat5-adpb" target="_blank">NYC Department of Information & Telecommunications (DoITT)</a></p>
|
|
130
|
+
</div>
|
|
131
|
+
</div>
|
|
132
|
+
</div>
|
|
133
|
+
<div class="modal-footer">
|
|
134
|
+
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
|
135
|
+
</div>
|
|
136
|
+
</div><!-- /.modal-content -->
|
|
137
|
+
</div><!-- /.modal-dialog -->
|
|
138
|
+
</div><!-- /.modal -->
|
|
139
|
+
|
|
140
|
+
<div class="modal fade" id="legendModal" tabindex="-1" role="dialog">
|
|
141
|
+
<div class="modal-dialog">
|
|
142
|
+
<div class="modal-content">
|
|
143
|
+
<div class="modal-header">
|
|
144
|
+
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
|
145
|
+
<h4 class="modal-title">Map Legend</h4>
|
|
146
|
+
</div>
|
|
147
|
+
<div class="modal-body">
|
|
148
|
+
<p>Map Legend goes here...</p>
|
|
149
|
+
</div>
|
|
150
|
+
<div class="modal-footer">
|
|
151
|
+
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
|
152
|
+
</div>
|
|
153
|
+
</div><!-- /.modal-content -->
|
|
154
|
+
</div><!-- /.modal-dialog -->
|
|
155
|
+
</div><!-- /.modal -->
|
|
156
|
+
|
|
157
|
+
<div class="modal fade" id="loginModal" tabindex="-1" role="dialog">
|
|
158
|
+
<div class="modal-dialog modal-sm">
|
|
159
|
+
<div class="modal-content">
|
|
160
|
+
<div class="modal-header">
|
|
161
|
+
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
|
162
|
+
<h4 class="modal-title">Login</h4>
|
|
163
|
+
</div>
|
|
164
|
+
<div class="modal-body">
|
|
165
|
+
<form id="contact-form">
|
|
166
|
+
<fieldset>
|
|
167
|
+
<div class="form-group">
|
|
168
|
+
<label for="name">Username:</label>
|
|
169
|
+
<input type="text" class="form-control" id="username">
|
|
170
|
+
</div>
|
|
171
|
+
<div class="form-group">
|
|
172
|
+
<label for="email">Password:</label>
|
|
173
|
+
<input type="password" class="form-control" id="password">
|
|
174
|
+
</div>
|
|
175
|
+
</fieldset>
|
|
176
|
+
</form>
|
|
177
|
+
</div>
|
|
178
|
+
<div class="modal-footer">
|
|
179
|
+
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
|
|
180
|
+
<button type="submit" class="btn btn-primary" data-dismiss="modal">Login</button>
|
|
181
|
+
</div>
|
|
182
|
+
</div><!-- /.modal-content -->
|
|
183
|
+
</div><!-- /.modal-dialog -->
|
|
184
|
+
</div><!-- /.modal -->
|
|
185
|
+
|
|
186
|
+
<div class="modal fade" id="featureModal" tabindex="-1" role="dialog">
|
|
187
|
+
<div class="modal-dialog">
|
|
188
|
+
<div class="modal-content">
|
|
189
|
+
<div class="modal-header">
|
|
190
|
+
<button class="close" type="button" data-dismiss="modal" aria-hidden="true">×</button>
|
|
191
|
+
<h4 class="modal-title text-primary" id="feature-title"></h4>
|
|
192
|
+
</div>
|
|
193
|
+
<div class="modal-body" id="feature-info"></div>
|
|
194
|
+
<div class="modal-footer">
|
|
195
|
+
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
|
196
|
+
</div>
|
|
197
|
+
</div><!-- /.modal-content -->
|
|
198
|
+
</div><!-- /.modal-dialog -->
|
|
199
|
+
</div><!-- /.modal -->
|
|
200
|
+
|
|
201
|
+
<div class="modal fade" id="attributionModal" tabindex="-1" role="dialog">
|
|
202
|
+
<div class="modal-dialog">
|
|
203
|
+
<div class="modal-content">
|
|
204
|
+
<div class="modal-header">
|
|
205
|
+
<button class="close" type="button" data-dismiss="modal" aria-hidden="true">×</button>
|
|
206
|
+
<h4 class="modal-title">
|
|
207
|
+
Developed by <a href='http://bryanmcbride.com'>bryanmcbride.com</a>
|
|
208
|
+
</h4>
|
|
209
|
+
</div>
|
|
210
|
+
<div class="modal-body">
|
|
211
|
+
<div id="attribution"></div>
|
|
212
|
+
</div>
|
|
213
|
+
</div><!-- /.modal-content -->
|
|
214
|
+
</div><!-- /.modal-dialog -->
|
|
215
|
+
</div><!-- /.modal -->
|
|
216
|
+
<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
|
|
217
|
+
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
|
|
218
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/typeahead.js/0.10.5/typeahead.bundle.min.js"></script>
|
|
219
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/3.0.3/handlebars.min.js"></script>
|
|
220
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/list.js/1.1.1/list.min.js"></script>
|
|
221
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/leaflet.js"></script>
|
|
222
|
+
<script src="https://api.tiles.mapbox.com/mapbox.js/plugins/leaflet-markercluster/v0.4.0/leaflet.markercluster.js"></script>
|
|
223
|
+
<script src="https://api.tiles.mapbox.com/mapbox.js/plugins/leaflet-locatecontrol/v0.43.0/L.Control.Locate.min.js"></script>
|
|
224
|
+
<script src="assets/leaflet-groupedlayercontrol/leaflet.groupedlayercontrol.js"></script>
|
|
225
|
+
<script src="assets/js/app.js"></script>
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
<div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
|
|
2
|
+
<div class="container-fluid">
|
|
3
|
+
<div class="navbar-header">
|
|
4
|
+
<div class="navbar-icon-container">
|
|
5
|
+
<a href="#" class="navbar-icon pull-right visible-xs" id="nav-btn"><i class="fa fa-bars fa-lg white"></i></a>
|
|
6
|
+
<a href="#" class="navbar-icon pull-right visible-xs" id="sidebar-toggle-btn"><i class="fa fa-search fa-lg white"></i></a>
|
|
7
|
+
</div>
|
|
8
|
+
<a class="navbar-brand" href="#">BootLeaf</a>
|
|
9
|
+
</div>
|
|
10
|
+
<div class="navbar-collapse collapse">
|
|
11
|
+
<form class="navbar-form navbar-right" role="search">
|
|
12
|
+
<div class="form-group has-feedback">
|
|
13
|
+
<input id="searchbox" type="text" placeholder="Search" class="form-control">
|
|
14
|
+
<span id="searchicon" class="fa fa-search form-control-feedback"></span>
|
|
15
|
+
</div>
|
|
16
|
+
</form>
|
|
17
|
+
<ul class="nav navbar-nav">
|
|
18
|
+
<li><a href="#" data-toggle="collapse" data-target=".navbar-collapse.in" id="about-btn"><i class="fa fa-question-circle white"></i> About</a></li>
|
|
19
|
+
<li class="dropdown">
|
|
20
|
+
<a id="toolsDrop" href="#" role="button" class="dropdown-toggle" data-toggle="dropdown"><i class="fa fa-globe white"></i> Tools <b class="caret"></b></a>
|
|
21
|
+
<ul class="dropdown-menu">
|
|
22
|
+
<li><a href="#" data-toggle="collapse" data-target=".navbar-collapse.in" id="full-extent-btn"><i class="fa fa-arrows-alt"></i> Zoom To Full Extent</a></li>
|
|
23
|
+
<li><a href="#" data-toggle="collapse" data-target=".navbar-collapse.in" id="legend-btn"><i class="fa fa-picture-o"></i> Show Legend</a></li>
|
|
24
|
+
<li class="divider hidden-xs"></li>
|
|
25
|
+
<li><a href="#" data-toggle="collapse" data-target=".navbar-collapse.in" id="login-btn"><i class="fa fa-user"></i> Login</a></li>
|
|
26
|
+
</ul>
|
|
27
|
+
</li>
|
|
28
|
+
<li class="dropdown">
|
|
29
|
+
<a class="dropdown-toggle" id="downloadDrop" href="#" role="button" data-toggle="dropdown"><i class="fa fa-cloud-download white"></i> Download <b class="caret"></b></a>
|
|
30
|
+
<ul class="dropdown-menu">
|
|
31
|
+
<li><a href="data/boroughs.geojson" download="boroughs.geojson" target="_blank" data-toggle="collapse" data-target=".navbar-collapse.in"><i class="fa fa-download"></i> Boroughs</a></li>
|
|
32
|
+
<li><a href="data/subways.geojson" download="subways.geojson" target="_blank" data-toggle="collapse" data-target=".navbar-collapse.in"><i class="fa fa-download"></i> Subway Lines</a></li>
|
|
33
|
+
<li><a href="data/DOITT_THEATER_01_13SEPT2010.geojson" download="theaters.geojson" target="_blank" data-toggle="collapse" data-target=".navbar-collapse.in"><i class="fa fa-download"></i> Theaters</a></li>
|
|
34
|
+
<li><a href="data/DOITT_MUSEUM_01_13SEPT2010.geojson" download="museums.geojson" target="_blank" data-toggle="collapse" data-target=".navbar-collapse.in"><i class="fa fa-download"></i> Museums</a></li>
|
|
35
|
+
</ul>
|
|
36
|
+
</li>
|
|
37
|
+
<li class="hidden-xs"><a href="#" data-toggle="collapse" data-target=".navbar-collapse.in" id="list-btn"><i class="fa fa-list white"></i> POI List</a></li>
|
|
38
|
+
</ul>
|
|
39
|
+
</div><!--/.navbar-collapse -->
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@import "web-mapping";
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
data/assets/js/app.js
ADDED
|
@@ -0,0 +1,606 @@
|
|
|
1
|
+
var map, featureList, boroughSearch = [], theaterSearch = [], museumSearch = [];
|
|
2
|
+
|
|
3
|
+
$(window).resize(function() {
|
|
4
|
+
sizeLayerControl();
|
|
5
|
+
});
|
|
6
|
+
|
|
7
|
+
$(document).on("click", ".feature-row", function(e) {
|
|
8
|
+
$(document).off("mouseout", ".feature-row", clearHighlight);
|
|
9
|
+
sidebarClick(parseInt($(this).attr("id"), 10));
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
if ( !("ontouchstart" in window) ) {
|
|
13
|
+
$(document).on("mouseover", ".feature-row", function(e) {
|
|
14
|
+
highlight.clearLayers().addLayer(L.circleMarker([$(this).attr("lat"), $(this).attr("lng")], highlightStyle));
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
$(document).on("mouseout", ".feature-row", clearHighlight);
|
|
19
|
+
|
|
20
|
+
$("#about-btn").click(function() {
|
|
21
|
+
$("#aboutModal").modal("show");
|
|
22
|
+
$(".navbar-collapse.in").collapse("hide");
|
|
23
|
+
return false;
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
$("#full-extent-btn").click(function() {
|
|
27
|
+
map.fitBounds(boroughs.getBounds());
|
|
28
|
+
$(".navbar-collapse.in").collapse("hide");
|
|
29
|
+
return false;
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
$("#legend-btn").click(function() {
|
|
33
|
+
$("#legendModal").modal("show");
|
|
34
|
+
$(".navbar-collapse.in").collapse("hide");
|
|
35
|
+
return false;
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
$("#login-btn").click(function() {
|
|
39
|
+
$("#loginModal").modal("show");
|
|
40
|
+
$(".navbar-collapse.in").collapse("hide");
|
|
41
|
+
return false;
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
$("#list-btn").click(function() {
|
|
45
|
+
animateSidebar();
|
|
46
|
+
return false;
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
$("#nav-btn").click(function() {
|
|
50
|
+
$(".navbar-collapse").collapse("toggle");
|
|
51
|
+
return false;
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
$("#sidebar-toggle-btn").click(function() {
|
|
55
|
+
animateSidebar();
|
|
56
|
+
return false;
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
$("#sidebar-hide-btn").click(function() {
|
|
60
|
+
animateSidebar();
|
|
61
|
+
return false;
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
function animateSidebar() {
|
|
65
|
+
$("#sidebar").animate({
|
|
66
|
+
width: "toggle"
|
|
67
|
+
}, 350, function() {
|
|
68
|
+
map.invalidateSize();
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function sizeLayerControl() {
|
|
73
|
+
$(".leaflet-control-layers").css("max-height", $("#map").height() - 50);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function clearHighlight() {
|
|
77
|
+
highlight.clearLayers();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function sidebarClick(id) {
|
|
81
|
+
var layer = markerClusters.getLayer(id);
|
|
82
|
+
map.setView([layer.getLatLng().lat, layer.getLatLng().lng], 17);
|
|
83
|
+
layer.fire("click");
|
|
84
|
+
/* Hide sidebar and go to the map on small screens */
|
|
85
|
+
if (document.body.clientWidth <= 767) {
|
|
86
|
+
$("#sidebar").hide();
|
|
87
|
+
map.invalidateSize();
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function syncSidebar() {
|
|
92
|
+
/* Empty sidebar features */
|
|
93
|
+
$("#feature-list tbody").empty();
|
|
94
|
+
/* Loop through theaters layer and add only features which are in the map bounds */
|
|
95
|
+
theaters.eachLayer(function (layer) {
|
|
96
|
+
if (map.hasLayer(theaterLayer)) {
|
|
97
|
+
if (map.getBounds().contains(layer.getLatLng())) {
|
|
98
|
+
$("#feature-list tbody").append('<tr class="feature-row" id="' + L.stamp(layer) + '" lat="' + layer.getLatLng().lat + '" lng="' + layer.getLatLng().lng + '"><td style="vertical-align: middle;"><img width="16" height="18" src="assets/img/theater.png"></td><td class="feature-name">' + layer.feature.properties.NAME + '</td><td style="vertical-align: middle;"><i class="fa fa-chevron-right pull-right"></i></td></tr>');
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
/* Loop through museums layer and add only features which are in the map bounds */
|
|
103
|
+
museums.eachLayer(function (layer) {
|
|
104
|
+
if (map.hasLayer(museumLayer)) {
|
|
105
|
+
if (map.getBounds().contains(layer.getLatLng())) {
|
|
106
|
+
$("#feature-list tbody").append('<tr class="feature-row" id="' + L.stamp(layer) + '" lat="' + layer.getLatLng().lat + '" lng="' + layer.getLatLng().lng + '"><td style="vertical-align: middle;"><img width="16" height="18" src="assets/img/museum.png"></td><td class="feature-name">' + layer.feature.properties.NAME + '</td><td style="vertical-align: middle;"><i class="fa fa-chevron-right pull-right"></i></td></tr>');
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
/* Update list.js featureList */
|
|
111
|
+
featureList = new List("features", {
|
|
112
|
+
valueNames: ["feature-name"]
|
|
113
|
+
});
|
|
114
|
+
featureList.sort("feature-name", {
|
|
115
|
+
order: "asc"
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/* Basemap Layers */
|
|
120
|
+
var cartoLight = L.tileLayer("https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png", {
|
|
121
|
+
maxZoom: 19,
|
|
122
|
+
attribution: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, © <a href="https://cartodb.com/attributions">CartoDB</a>'
|
|
123
|
+
});
|
|
124
|
+
var usgsImagery = L.layerGroup([L.tileLayer("http://basemap.nationalmap.gov/arcgis/rest/services/USGSImageryOnly/MapServer/tile/{z}/{y}/{x}", {
|
|
125
|
+
maxZoom: 15,
|
|
126
|
+
}), L.tileLayer.wms("http://raster.nationalmap.gov/arcgis/services/Orthoimagery/USGS_EROS_Ortho_SCALE/ImageServer/WMSServer?", {
|
|
127
|
+
minZoom: 16,
|
|
128
|
+
maxZoom: 19,
|
|
129
|
+
layers: "0",
|
|
130
|
+
format: 'image/jpeg',
|
|
131
|
+
transparent: true,
|
|
132
|
+
attribution: "Aerial Imagery courtesy USGS"
|
|
133
|
+
})]);
|
|
134
|
+
|
|
135
|
+
/* Overlay Layers */
|
|
136
|
+
var highlight = L.geoJson(null);
|
|
137
|
+
var highlightStyle = {
|
|
138
|
+
stroke: false,
|
|
139
|
+
fillColor: "#00FFFF",
|
|
140
|
+
fillOpacity: 0.7,
|
|
141
|
+
radius: 10
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
var boroughs = L.geoJson(null, {
|
|
145
|
+
style: function (feature) {
|
|
146
|
+
return {
|
|
147
|
+
color: "black",
|
|
148
|
+
fill: false,
|
|
149
|
+
opacity: 1,
|
|
150
|
+
clickable: false
|
|
151
|
+
};
|
|
152
|
+
},
|
|
153
|
+
onEachFeature: function (feature, layer) {
|
|
154
|
+
boroughSearch.push({
|
|
155
|
+
name: layer.feature.properties.BoroName,
|
|
156
|
+
source: "Boroughs",
|
|
157
|
+
id: L.stamp(layer),
|
|
158
|
+
bounds: layer.getBounds()
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
$.getJSON("data/boroughs.geojson", function (data) {
|
|
163
|
+
boroughs.addData(data);
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
//Create a color dictionary based off of subway route_id
|
|
167
|
+
var subwayColors = {"1":"#ff3135", "2":"#ff3135", "3":"ff3135", "4":"#009b2e",
|
|
168
|
+
"5":"#009b2e", "6":"#009b2e", "7":"#ce06cb", "A":"#fd9a00", "C":"#fd9a00",
|
|
169
|
+
"E":"#fd9a00", "SI":"#fd9a00","H":"#fd9a00", "Air":"#ffff00", "B":"#ffff00",
|
|
170
|
+
"D":"#ffff00", "F":"#ffff00", "M":"#ffff00", "G":"#9ace00", "FS":"#6e6e6e",
|
|
171
|
+
"GS":"#6e6e6e", "J":"#976900", "Z":"#976900", "L":"#969696", "N":"#ffff00",
|
|
172
|
+
"Q":"#ffff00", "R":"#ffff00" };
|
|
173
|
+
|
|
174
|
+
var subwayLines = L.geoJson(null, {
|
|
175
|
+
style: function (feature) {
|
|
176
|
+
return {
|
|
177
|
+
color: subwayColors[feature.properties.route_id],
|
|
178
|
+
weight: 3,
|
|
179
|
+
opacity: 1
|
|
180
|
+
};
|
|
181
|
+
},
|
|
182
|
+
onEachFeature: function (feature, layer) {
|
|
183
|
+
if (feature.properties) {
|
|
184
|
+
var content = "<table class='table table-striped table-bordered table-condensed'>" + "<tr><th>Division</th><td>" + feature.properties.Division + "</td></tr>" + "<tr><th>Line</th><td>" + feature.properties.Line + "</td></tr>" + "<table>";
|
|
185
|
+
layer.on({
|
|
186
|
+
click: function (e) {
|
|
187
|
+
$("#feature-title").html(feature.properties.Line);
|
|
188
|
+
$("#feature-info").html(content);
|
|
189
|
+
$("#featureModal").modal("show");
|
|
190
|
+
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
layer.on({
|
|
195
|
+
mouseover: function (e) {
|
|
196
|
+
var layer = e.target;
|
|
197
|
+
layer.setStyle({
|
|
198
|
+
weight: 3,
|
|
199
|
+
color: "#00FFFF",
|
|
200
|
+
opacity: 1
|
|
201
|
+
});
|
|
202
|
+
if (!L.Browser.ie && !L.Browser.opera) {
|
|
203
|
+
layer.bringToFront();
|
|
204
|
+
}
|
|
205
|
+
},
|
|
206
|
+
mouseout: function (e) {
|
|
207
|
+
subwayLines.resetStyle(e.target);
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
$.getJSON("data/subways.geojson", function (data) {
|
|
213
|
+
subwayLines.addData(data);
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
/* Single marker cluster layer to hold all clusters */
|
|
217
|
+
var markerClusters = new L.MarkerClusterGroup({
|
|
218
|
+
spiderfyOnMaxZoom: true,
|
|
219
|
+
showCoverageOnHover: false,
|
|
220
|
+
zoomToBoundsOnClick: true,
|
|
221
|
+
disableClusteringAtZoom: 16
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
/* Empty layer placeholder to add to layer control for listening when to add/remove theaters to markerClusters layer */
|
|
225
|
+
var theaterLayer = L.geoJson(null);
|
|
226
|
+
var theaters = L.geoJson(null, {
|
|
227
|
+
pointToLayer: function (feature, latlng) {
|
|
228
|
+
return L.marker(latlng, {
|
|
229
|
+
icon: L.icon({
|
|
230
|
+
iconUrl: "assets/img/theater.png",
|
|
231
|
+
iconSize: [24, 28],
|
|
232
|
+
iconAnchor: [12, 28],
|
|
233
|
+
popupAnchor: [0, -25]
|
|
234
|
+
}),
|
|
235
|
+
title: feature.properties.NAME,
|
|
236
|
+
riseOnHover: true
|
|
237
|
+
});
|
|
238
|
+
},
|
|
239
|
+
onEachFeature: function (feature, layer) {
|
|
240
|
+
if (feature.properties) {
|
|
241
|
+
var content = "<table class='table table-striped table-bordered table-condensed'>" + "<tr><th>Name</th><td>" + feature.properties.NAME + "</td></tr>" + "<tr><th>Phone</th><td>" + feature.properties.TEL + "</td></tr>" + "<tr><th>Address</th><td>" + feature.properties.ADDRESS1 + "</td></tr>" + "<tr><th>Website</th><td><a class='url-break' href='" + feature.properties.URL + "' target='_blank'>" + feature.properties.URL + "</a></td></tr>" + "<table>";
|
|
242
|
+
layer.on({
|
|
243
|
+
click: function (e) {
|
|
244
|
+
$("#feature-title").html(feature.properties.NAME);
|
|
245
|
+
$("#feature-info").html(content);
|
|
246
|
+
$("#featureModal").modal("show");
|
|
247
|
+
highlight.clearLayers().addLayer(L.circleMarker([feature.geometry.coordinates[1], feature.geometry.coordinates[0]], highlightStyle));
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
$("#feature-list tbody").append('<tr class="feature-row" id="' + L.stamp(layer) + '" lat="' + layer.getLatLng().lat + '" lng="' + layer.getLatLng().lng + '"><td style="vertical-align: middle;"><img width="16" height="18" src="assets/img/theater.png"></td><td class="feature-name">' + layer.feature.properties.NAME + '</td><td style="vertical-align: middle;"><i class="fa fa-chevron-right pull-right"></i></td></tr>');
|
|
251
|
+
theaterSearch.push({
|
|
252
|
+
name: layer.feature.properties.NAME,
|
|
253
|
+
address: layer.feature.properties.ADDRESS1,
|
|
254
|
+
source: "Theaters",
|
|
255
|
+
id: L.stamp(layer),
|
|
256
|
+
lat: layer.feature.geometry.coordinates[1],
|
|
257
|
+
lng: layer.feature.geometry.coordinates[0]
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
$.getJSON("data/DOITT_THEATER_01_13SEPT2010.geojson", function (data) {
|
|
263
|
+
theaters.addData(data);
|
|
264
|
+
map.addLayer(theaterLayer);
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
/* Empty layer placeholder to add to layer control for listening when to add/remove museums to markerClusters layer */
|
|
268
|
+
var museumLayer = L.geoJson(null);
|
|
269
|
+
var museums = L.geoJson(null, {
|
|
270
|
+
pointToLayer: function (feature, latlng) {
|
|
271
|
+
return L.marker(latlng, {
|
|
272
|
+
icon: L.icon({
|
|
273
|
+
iconUrl: "assets/img/museum.png",
|
|
274
|
+
iconSize: [24, 28],
|
|
275
|
+
iconAnchor: [12, 28],
|
|
276
|
+
popupAnchor: [0, -25]
|
|
277
|
+
}),
|
|
278
|
+
title: feature.properties.NAME,
|
|
279
|
+
riseOnHover: true
|
|
280
|
+
});
|
|
281
|
+
},
|
|
282
|
+
onEachFeature: function (feature, layer) {
|
|
283
|
+
if (feature.properties) {
|
|
284
|
+
var content = "<table class='table table-striped table-bordered table-condensed'>" + "<tr><th>Name</th><td>" + feature.properties.NAME + "</td></tr>" + "<tr><th>Phone</th><td>" + feature.properties.TEL + "</td></tr>" + "<tr><th>Address</th><td>" + feature.properties.ADRESS1 + "</td></tr>" + "<tr><th>Website</th><td><a class='url-break' href='" + feature.properties.URL + "' target='_blank'>" + feature.properties.URL + "</a></td></tr>" + "<table>";
|
|
285
|
+
layer.on({
|
|
286
|
+
click: function (e) {
|
|
287
|
+
$("#feature-title").html(feature.properties.NAME);
|
|
288
|
+
$("#feature-info").html(content);
|
|
289
|
+
$("#featureModal").modal("show");
|
|
290
|
+
highlight.clearLayers().addLayer(L.circleMarker([feature.geometry.coordinates[1], feature.geometry.coordinates[0]], highlightStyle));
|
|
291
|
+
}
|
|
292
|
+
});
|
|
293
|
+
$("#feature-list tbody").append('<tr class="feature-row" id="' + L.stamp(layer) + '" lat="' + layer.getLatLng().lat + '" lng="' + layer.getLatLng().lng + '"><td style="vertical-align: middle;"><img width="16" height="18" src="assets/img/museum.png"></td><td class="feature-name">' + layer.feature.properties.NAME + '</td><td style="vertical-align: middle;"><i class="fa fa-chevron-right pull-right"></i></td></tr>');
|
|
294
|
+
museumSearch.push({
|
|
295
|
+
name: layer.feature.properties.NAME,
|
|
296
|
+
address: layer.feature.properties.ADRESS1,
|
|
297
|
+
source: "Museums",
|
|
298
|
+
id: L.stamp(layer),
|
|
299
|
+
lat: layer.feature.geometry.coordinates[1],
|
|
300
|
+
lng: layer.feature.geometry.coordinates[0]
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
});
|
|
305
|
+
$.getJSON("data/DOITT_MUSEUM_01_13SEPT2010.geojson", function (data) {
|
|
306
|
+
museums.addData(data);
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
map = L.map("map", {
|
|
310
|
+
zoom: 10,
|
|
311
|
+
center: [40.702222, -73.979378],
|
|
312
|
+
layers: [cartoLight, boroughs, markerClusters, highlight],
|
|
313
|
+
zoomControl: false,
|
|
314
|
+
attributionControl: false
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
/* Layer control listeners that allow for a single markerClusters layer */
|
|
318
|
+
map.on("overlayadd", function(e) {
|
|
319
|
+
if (e.layer === theaterLayer) {
|
|
320
|
+
markerClusters.addLayer(theaters);
|
|
321
|
+
syncSidebar();
|
|
322
|
+
}
|
|
323
|
+
if (e.layer === museumLayer) {
|
|
324
|
+
markerClusters.addLayer(museums);
|
|
325
|
+
syncSidebar();
|
|
326
|
+
}
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
map.on("overlayremove", function(e) {
|
|
330
|
+
if (e.layer === theaterLayer) {
|
|
331
|
+
markerClusters.removeLayer(theaters);
|
|
332
|
+
syncSidebar();
|
|
333
|
+
}
|
|
334
|
+
if (e.layer === museumLayer) {
|
|
335
|
+
markerClusters.removeLayer(museums);
|
|
336
|
+
syncSidebar();
|
|
337
|
+
}
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
/* Filter sidebar feature list to only show features in current map bounds */
|
|
341
|
+
map.on("moveend", function (e) {
|
|
342
|
+
syncSidebar();
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
/* Clear feature highlight when map is clicked */
|
|
346
|
+
map.on("click", function(e) {
|
|
347
|
+
highlight.clearLayers();
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
/* Attribution control */
|
|
351
|
+
function updateAttribution(e) {
|
|
352
|
+
$.each(map._layers, function(index, layer) {
|
|
353
|
+
if (layer.getAttribution) {
|
|
354
|
+
$("#attribution").html((layer.getAttribution()));
|
|
355
|
+
}
|
|
356
|
+
});
|
|
357
|
+
}
|
|
358
|
+
map.on("layeradd", updateAttribution);
|
|
359
|
+
map.on("layerremove", updateAttribution);
|
|
360
|
+
|
|
361
|
+
var attributionControl = L.control({
|
|
362
|
+
position: "bottomright"
|
|
363
|
+
});
|
|
364
|
+
attributionControl.onAdd = function (map) {
|
|
365
|
+
var div = L.DomUtil.create("div", "leaflet-control-attribution");
|
|
366
|
+
div.innerHTML = "<span class='hidden-xs'>Developed by <a href='http://bryanmcbride.com'>bryanmcbride.com</a> | </span><a href='#' onclick='$(\"#attributionModal\").modal(\"show\"); return false;'>Attribution</a>";
|
|
367
|
+
return div;
|
|
368
|
+
};
|
|
369
|
+
map.addControl(attributionControl);
|
|
370
|
+
|
|
371
|
+
var zoomControl = L.control.zoom({
|
|
372
|
+
position: "bottomright"
|
|
373
|
+
}).addTo(map);
|
|
374
|
+
|
|
375
|
+
/* GPS enabled geolocation control set to follow the user's location */
|
|
376
|
+
var locateControl = L.control.locate({
|
|
377
|
+
position: "bottomright",
|
|
378
|
+
drawCircle: true,
|
|
379
|
+
follow: true,
|
|
380
|
+
setView: true,
|
|
381
|
+
keepCurrentZoomLevel: true,
|
|
382
|
+
markerStyle: {
|
|
383
|
+
weight: 1,
|
|
384
|
+
opacity: 0.8,
|
|
385
|
+
fillOpacity: 0.8
|
|
386
|
+
},
|
|
387
|
+
circleStyle: {
|
|
388
|
+
weight: 1,
|
|
389
|
+
clickable: false
|
|
390
|
+
},
|
|
391
|
+
icon: "fa fa-location-arrow",
|
|
392
|
+
metric: false,
|
|
393
|
+
strings: {
|
|
394
|
+
title: "My location",
|
|
395
|
+
popup: "You are within {distance} {unit} from this point",
|
|
396
|
+
outsideMapBoundsMsg: "You seem located outside the boundaries of the map"
|
|
397
|
+
},
|
|
398
|
+
locateOptions: {
|
|
399
|
+
maxZoom: 18,
|
|
400
|
+
watch: true,
|
|
401
|
+
enableHighAccuracy: true,
|
|
402
|
+
maximumAge: 10000,
|
|
403
|
+
timeout: 10000
|
|
404
|
+
}
|
|
405
|
+
}).addTo(map);
|
|
406
|
+
|
|
407
|
+
/* Larger screens get expanded layer control and visible sidebar */
|
|
408
|
+
if (document.body.clientWidth <= 767) {
|
|
409
|
+
var isCollapsed = true;
|
|
410
|
+
} else {
|
|
411
|
+
var isCollapsed = false;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
var baseLayers = {
|
|
415
|
+
"Street Map": cartoLight,
|
|
416
|
+
"Aerial Imagery": usgsImagery
|
|
417
|
+
};
|
|
418
|
+
|
|
419
|
+
var groupedOverlays = {
|
|
420
|
+
"Points of Interest": {
|
|
421
|
+
"<img src='assets/img/theater.png' width='24' height='28'> Theaters": theaterLayer,
|
|
422
|
+
"<img src='assets/img/museum.png' width='24' height='28'> Museums": museumLayer
|
|
423
|
+
},
|
|
424
|
+
"Reference": {
|
|
425
|
+
"Boroughs": boroughs,
|
|
426
|
+
"Subway Lines": subwayLines
|
|
427
|
+
}
|
|
428
|
+
};
|
|
429
|
+
|
|
430
|
+
var layerControl = L.control.groupedLayers(baseLayers, groupedOverlays, {
|
|
431
|
+
collapsed: isCollapsed
|
|
432
|
+
}).addTo(map);
|
|
433
|
+
|
|
434
|
+
/* Highlight search box text on click */
|
|
435
|
+
$("#searchbox").click(function () {
|
|
436
|
+
$(this).select();
|
|
437
|
+
});
|
|
438
|
+
|
|
439
|
+
/* Prevent hitting enter from refreshing the page */
|
|
440
|
+
$("#searchbox").keypress(function (e) {
|
|
441
|
+
if (e.which == 13) {
|
|
442
|
+
e.preventDefault();
|
|
443
|
+
}
|
|
444
|
+
});
|
|
445
|
+
|
|
446
|
+
$("#featureModal").on("hidden.bs.modal", function (e) {
|
|
447
|
+
$(document).on("mouseout", ".feature-row", clearHighlight);
|
|
448
|
+
});
|
|
449
|
+
|
|
450
|
+
/* Typeahead search functionality */
|
|
451
|
+
$(document).one("ajaxStop", function () {
|
|
452
|
+
$("#loading").hide();
|
|
453
|
+
sizeLayerControl();
|
|
454
|
+
/* Fit map to boroughs bounds */
|
|
455
|
+
map.fitBounds(boroughs.getBounds());
|
|
456
|
+
featureList = new List("features", {valueNames: ["feature-name"]});
|
|
457
|
+
featureList.sort("feature-name", {order:"asc"});
|
|
458
|
+
|
|
459
|
+
var boroughsBH = new Bloodhound({
|
|
460
|
+
name: "Boroughs",
|
|
461
|
+
datumTokenizer: function (d) {
|
|
462
|
+
return Bloodhound.tokenizers.whitespace(d.name);
|
|
463
|
+
},
|
|
464
|
+
queryTokenizer: Bloodhound.tokenizers.whitespace,
|
|
465
|
+
local: boroughSearch,
|
|
466
|
+
limit: 10
|
|
467
|
+
});
|
|
468
|
+
|
|
469
|
+
var theatersBH = new Bloodhound({
|
|
470
|
+
name: "Theaters",
|
|
471
|
+
datumTokenizer: function (d) {
|
|
472
|
+
return Bloodhound.tokenizers.whitespace(d.name);
|
|
473
|
+
},
|
|
474
|
+
queryTokenizer: Bloodhound.tokenizers.whitespace,
|
|
475
|
+
local: theaterSearch,
|
|
476
|
+
limit: 10
|
|
477
|
+
});
|
|
478
|
+
|
|
479
|
+
var museumsBH = new Bloodhound({
|
|
480
|
+
name: "Museums",
|
|
481
|
+
datumTokenizer: function (d) {
|
|
482
|
+
return Bloodhound.tokenizers.whitespace(d.name);
|
|
483
|
+
},
|
|
484
|
+
queryTokenizer: Bloodhound.tokenizers.whitespace,
|
|
485
|
+
local: museumSearch,
|
|
486
|
+
limit: 10
|
|
487
|
+
});
|
|
488
|
+
|
|
489
|
+
var geonamesBH = new Bloodhound({
|
|
490
|
+
name: "GeoNames",
|
|
491
|
+
datumTokenizer: function (d) {
|
|
492
|
+
return Bloodhound.tokenizers.whitespace(d.name);
|
|
493
|
+
},
|
|
494
|
+
queryTokenizer: Bloodhound.tokenizers.whitespace,
|
|
495
|
+
remote: {
|
|
496
|
+
url: "http://api.geonames.org/searchJSON?username=bootleaf&featureClass=P&maxRows=5&countryCode=US&name_startsWith=%QUERY",
|
|
497
|
+
filter: function (data) {
|
|
498
|
+
return $.map(data.geonames, function (result) {
|
|
499
|
+
return {
|
|
500
|
+
name: result.name + ", " + result.adminCode1,
|
|
501
|
+
lat: result.lat,
|
|
502
|
+
lng: result.lng,
|
|
503
|
+
source: "GeoNames"
|
|
504
|
+
};
|
|
505
|
+
});
|
|
506
|
+
},
|
|
507
|
+
ajax: {
|
|
508
|
+
beforeSend: function (jqXhr, settings) {
|
|
509
|
+
settings.url += "&east=" + map.getBounds().getEast() + "&west=" + map.getBounds().getWest() + "&north=" + map.getBounds().getNorth() + "&south=" + map.getBounds().getSouth();
|
|
510
|
+
$("#searchicon").removeClass("fa-search").addClass("fa-refresh fa-spin");
|
|
511
|
+
},
|
|
512
|
+
complete: function (jqXHR, status) {
|
|
513
|
+
$('#searchicon').removeClass("fa-refresh fa-spin").addClass("fa-search");
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
},
|
|
517
|
+
limit: 10
|
|
518
|
+
});
|
|
519
|
+
boroughsBH.initialize();
|
|
520
|
+
theatersBH.initialize();
|
|
521
|
+
museumsBH.initialize();
|
|
522
|
+
geonamesBH.initialize();
|
|
523
|
+
|
|
524
|
+
/* instantiate the typeahead UI */
|
|
525
|
+
$("#searchbox").typeahead({
|
|
526
|
+
minLength: 3,
|
|
527
|
+
highlight: true,
|
|
528
|
+
hint: false
|
|
529
|
+
}, {
|
|
530
|
+
name: "Boroughs",
|
|
531
|
+
displayKey: "name",
|
|
532
|
+
source: boroughsBH.ttAdapter(),
|
|
533
|
+
templates: {
|
|
534
|
+
header: "<h4 class='typeahead-header'>Boroughs</h4>"
|
|
535
|
+
}
|
|
536
|
+
}, {
|
|
537
|
+
name: "Theaters",
|
|
538
|
+
displayKey: "name",
|
|
539
|
+
source: theatersBH.ttAdapter(),
|
|
540
|
+
templates: {
|
|
541
|
+
header: "<h4 class='typeahead-header'><img src='assets/img/theater.png' width='24' height='28'> Theaters</h4>",
|
|
542
|
+
suggestion: Handlebars.compile(["{{name}}<br> <small>{{address}}</small>"].join(""))
|
|
543
|
+
}
|
|
544
|
+
}, {
|
|
545
|
+
name: "Museums",
|
|
546
|
+
displayKey: "name",
|
|
547
|
+
source: museumsBH.ttAdapter(),
|
|
548
|
+
templates: {
|
|
549
|
+
header: "<h4 class='typeahead-header'><img src='assets/img/museum.png' width='24' height='28'> Museums</h4>",
|
|
550
|
+
suggestion: Handlebars.compile(["{{name}}<br> <small>{{address}}</small>"].join(""))
|
|
551
|
+
}
|
|
552
|
+
}, {
|
|
553
|
+
name: "GeoNames",
|
|
554
|
+
displayKey: "name",
|
|
555
|
+
source: geonamesBH.ttAdapter(),
|
|
556
|
+
templates: {
|
|
557
|
+
header: "<h4 class='typeahead-header'><img src='assets/img/globe.png' width='25' height='25'> GeoNames</h4>"
|
|
558
|
+
}
|
|
559
|
+
}).on("typeahead:selected", function (obj, datum) {
|
|
560
|
+
if (datum.source === "Boroughs") {
|
|
561
|
+
map.fitBounds(datum.bounds);
|
|
562
|
+
}
|
|
563
|
+
if (datum.source === "Theaters") {
|
|
564
|
+
if (!map.hasLayer(theaterLayer)) {
|
|
565
|
+
map.addLayer(theaterLayer);
|
|
566
|
+
}
|
|
567
|
+
map.setView([datum.lat, datum.lng], 17);
|
|
568
|
+
if (map._layers[datum.id]) {
|
|
569
|
+
map._layers[datum.id].fire("click");
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
if (datum.source === "Museums") {
|
|
573
|
+
if (!map.hasLayer(museumLayer)) {
|
|
574
|
+
map.addLayer(museumLayer);
|
|
575
|
+
}
|
|
576
|
+
map.setView([datum.lat, datum.lng], 17);
|
|
577
|
+
if (map._layers[datum.id]) {
|
|
578
|
+
map._layers[datum.id].fire("click");
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
if (datum.source === "GeoNames") {
|
|
582
|
+
map.setView([datum.lat, datum.lng], 14);
|
|
583
|
+
}
|
|
584
|
+
if ($(".navbar-collapse").height() > 50) {
|
|
585
|
+
$(".navbar-collapse").collapse("hide");
|
|
586
|
+
}
|
|
587
|
+
}).on("typeahead:opened", function () {
|
|
588
|
+
$(".navbar-collapse.in").css("max-height", $(document).height() - $(".navbar-header").height());
|
|
589
|
+
$(".navbar-collapse.in").css("height", $(document).height() - $(".navbar-header").height());
|
|
590
|
+
}).on("typeahead:closed", function () {
|
|
591
|
+
$(".navbar-collapse.in").css("max-height", "");
|
|
592
|
+
$(".navbar-collapse.in").css("height", "");
|
|
593
|
+
});
|
|
594
|
+
$(".twitter-typeahead").css("position", "static");
|
|
595
|
+
$(".twitter-typeahead").css("display", "block");
|
|
596
|
+
});
|
|
597
|
+
|
|
598
|
+
// Leaflet patch to make layer control scrollable on touch browsers
|
|
599
|
+
var container = $(".leaflet-control-layers")[0];
|
|
600
|
+
if (!L.Browser.touch) {
|
|
601
|
+
L.DomEvent
|
|
602
|
+
.disableClickPropagation(container)
|
|
603
|
+
.disableScrollPropagation(container);
|
|
604
|
+
} else {
|
|
605
|
+
L.DomEvent.disableClickPropagation(container);
|
|
606
|
+
}
|