├── .eslintrc.json ├── .gitignore ├── .vscode ├── extensions.json ├── launch.json ├── settings.json └── tasks.json ├── .vscodeignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── data ├── csv │ ├── chicago-red-light-cameras.csv │ ├── usa-airports.csv │ ├── usa-state-capitals.csv │ ├── world-cities.csv │ └── world-countries.csv ├── geojson │ ├── chicago-red-light-cameras.geojson │ ├── usa-airports.geojson │ ├── usa-state-capitals.geojson │ ├── world-cities.geojson │ └── world-countries.geojson └── json │ ├── chicago-red-light-cameras.json │ ├── usa-airports.json │ ├── usa-state-capitals.json │ └── world-cities.json ├── docs └── images │ ├── data-table-notebook-examples.png │ ├── equals.png │ ├── heart.png │ ├── notebook.png │ ├── plus.png │ ├── unfolded-map-geojson.png │ ├── unfolded-map-notebook-renderer.png │ ├── unfolded-map-text-output.png │ └── unfolded.jfif ├── notebooks ├── chicago-red-light-cameras-pyolite.ipynb ├── chicago-red-light-cameras.restbook ├── usa-airports-net.ipynb ├── usa-state-capitals-typescript.ipynb ├── world-cities.restbook ├── world-countries.restbook └── world-gdp.restbook ├── package-lock.json ├── package.json ├── resources └── icons │ ├── map.png │ ├── map.svg │ └── unfolded.jfif ├── src ├── extension │ ├── extension.ts │ └── tsconfig.json ├── renderer │ ├── config.ts │ ├── css.d.ts │ ├── geoConverter.ts │ ├── index.ts │ ├── outputLoader.ts │ ├── renderer.ts │ ├── styles │ │ ├── mapbox-gl.css │ │ ├── styles.css │ │ └── uber-fonts.css │ ├── tsconfig.json │ └── unfoldedMap.js ├── test │ ├── checkNoTestProvider.ts │ ├── runTest.ts │ ├── suite │ │ ├── extension.test.ts │ │ └── index.ts │ └── tsconfig.json └── tsconfig-base.json ├── tsconfig.json └── webpack.config.js /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "parser": "@typescript-eslint/parser", 4 | "parserOptions": { 5 | "ecmaVersion": 6, 6 | "sourceType": "module" 7 | }, 8 | "plugins": [ 9 | "@typescript-eslint" 10 | ], 11 | "rules": { 12 | "@typescript-eslint/naming-convention": "warn", 13 | "@typescript-eslint/semi": "warn", 14 | "curly": "warn", 15 | "eqeqeq": "warn", 16 | "no-throw-literal": "warn", 17 | "semi": "off" 18 | }, 19 | "ignorePatterns": [ 20 | "**/*.d.ts" 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | out 3 | *.vsix 4 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See http://go.microsoft.com/fwlink/?LinkId=827846 3 | // for the documentation about the extensions.json format 4 | "recommendations": [ 5 | "dbaeumer.vscode-eslint", 6 | "tanhakabir.rest-book", 7 | "RandomFractalsInc.geo-data-viewer", 8 | "RandomFractalsInc.vscode-data-table", 9 | "RandomFractalsInc.vscode-data-preview" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | // A launch configuration that compiles the extension and then opens it inside a new window 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | { 6 | "version": "0.2.0", 7 | "configurations": [ 8 | { 9 | "name": "Run Extension", 10 | "type": "pwa-extensionHost", 11 | "request": "launch", 12 | "args": [ 13 | "--extensionDevelopmentPath=${workspaceFolder}" 14 | ], 15 | "outFiles": [ 16 | "${workspaceFolder}/out/**/*.js" 17 | ], 18 | "debugWebviews": { 19 | "urlFilter": "*notebookRenderer*" 20 | }, 21 | "trace": true, 22 | "preLaunchTask": "npm: dev" 23 | }, 24 | { 25 | "name": "Run Extension (no server)", 26 | "type": "extensionHost", 27 | "request": "launch", 28 | "args": [ 29 | "--extensionDevelopmentPath=${workspaceFolder}" 30 | ], 31 | "outFiles": [ 32 | "${workspaceFolder}/out/**/*.js" 33 | ], 34 | "debugWebviews": true, 35 | "preLaunchTask": "npm: watch" 36 | }, 37 | { 38 | "name": "Extension Tests", 39 | "type": "extensionHost", 40 | "request": "launch", 41 | "args": [ 42 | "--extensionDevelopmentPath=${workspaceFolder}", 43 | "--extensionTestsPath=${workspaceFolder}/out/test/suite/index" 44 | ], 45 | "outFiles": [ 46 | "${workspaceFolder}/out/test/**/*.js" 47 | ], 48 | "preLaunchTask": "${defaultBuildTask}" 49 | } 50 | ] 51 | } 52 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | "files.exclude": { 4 | "out": false // set this to true to hide the "out" folder with the compiled JS files 5 | }, 6 | "search.exclude": { 7 | "out": true // set this to false to include "out" folder in search results 8 | }, 9 | // Turn off tsc task auto detection since we have the necessary tasks as npm scripts 10 | "typescript.tsc.autoDetect": "off" 11 | } 12 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | // See https://go.microsoft.com/fwlink/?LinkId=733558 2 | // for the documentation about the tasks.json format 3 | { 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "type": "npm", 8 | "script": "dev", 9 | "problemMatcher": ["$tsc-watch", "$ts-checker-webpack-watch"], 10 | "isBackground": true, 11 | "presentation": { 12 | "reveal": "never" 13 | }, 14 | "group": { 15 | "kind": "build", 16 | "isDefault": true 17 | } 18 | }, 19 | { 20 | "type": "npm", 21 | "script": "watch", 22 | "problemMatcher": ["$tsc-watch", "$ts-checker-webpack-watch"], 23 | "isBackground": true, 24 | "presentation": { 25 | "reveal": "never" 26 | }, 27 | "group": "build" 28 | }, 29 | { 30 | "type": "npm", 31 | "script": "compile", 32 | "problemMatcher": ["$tsc", "$ts-checker-webpack"], 33 | "group": "build" 34 | } 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /.vscodeignore: -------------------------------------------------------------------------------- 1 | .vscode/** 2 | .vscode-test/** 3 | out/test/** 4 | src/** 5 | data/** 6 | notebooks/** 7 | docs/images/** 8 | 9 | .gitignore 10 | .github 11 | 12 | webpack.config.js 13 | node_modules 14 | 15 | **/.eslintrc.json 16 | **/*.map 17 | **/*.ts 18 | **/*.tsbuildinfo 19 | **/tsconfig.json 20 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | See [releases](https://github.com/RandomFractals/unfolded-map-renderer/releases) for source code and `unfolded-map-renderer-vX.X.X.vsix` extension package download. 4 | 5 | # v1.0.0 - [2021-11-13] 6 | 7 | - [#1](https://github.com/RandomFractals/unfolded-map-renderer/issues/1) 8 | Create Unfolded Map Renderer from keplergl notebook renderer code base 9 | - [#2](https://github.com/RandomFractals/unfolded-map-renderer/issues/2) 10 | Create Unfolded Map Renderer README 11 | - [#3](https://github.com/RandomFractals/unfolded-map-renderer/issues/3) 12 | Package and publish Unfolded Map Notebook Renderer alpha v. -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # unfolded-map-renderer 2 | 3 | [![Apache-2.0 License](https://img.shields.io/badge/license-Apache2-brightgreen.svg)](http://opensource.org/licenses/Apache-2.0) 4 | 5 | https://ko-fi.com/dataPixy 6 | 7 | 8 |

9 | 10 | 11 | 12 | 13 | 14 |
15 |
16 | Unfolded Map 🗺️ Notebook 📓 Renderer for VSCode 17 |

18 | 19 | See [Geo Data Viewer](https://github.com/RandomFractals/geo-data-viewer) 🗺️ vscode extension for advanced [Geo Data Analytics](https://marketplace.visualstudio.com/items?itemName=RandomFractalsInc.geo-data-viewer) with [kepler.gl](https://kepler.gl/) 20 | 21 | ## Unfolded Map 🗺️ Renderer 22 | 23 | Unfolded Map 🗺️ Notebook 📓 Renderer uses [Unfolded Map SDK](https://docs.unfolded.ai/map-sdk/javascript-map-sdk) JavaScript library for interactive preview of Geo datasets loaded in [VSCode Notebooks](https://code.visualstudio.com/api/extension-guides/notebook) 📚 24 | 25 | ![Unfolded Map 🗺️ Notebook 📓 Renderer](https://github.com/RandomFractals/unfolded-map-renderer/blob/main/docs/images/unfolded-map-notebook-renderer.png?raw=true 26 | "Unfolded Map 🗺️ Notebook 📓 Renderer") 27 | 28 | # Features 29 | 30 | - View Location data from `CSV`, `XML`, `JSON`, and [`GeoJSON`](https://www.rfc-editor.org/rfc/rfc7946.html) Notebook 📓 cell ⌗ data output on the [Unfolded Studio](https://kepler.gl) map 🗺️ 31 | - View `JSON`, `CSV`, and `XML` data without Geo Location information in `JSON` format in a scrollable text container with [`code pre-wrap`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/code) for a quick copy/paste to other places: 32 | 33 | ![Unfolded Map 🗺️ Renderer Text Output](https://github.com/RandomFractals/unfolded-map-renderer/blob/main/docs/images/unfolded-map-text-output.png?raw=true 34 | "Unfolded Map 🗺️ Renderer Text Output") 35 | 36 | # Supported Data Formats 37 | 38 | Unfolded Map 🗺️ Notebook 📓 Renderer supports loading Location data from the following output formats: 39 | 40 | | Data Mime Type | Location Data | Geo Location Processing Description | 41 | | --- | --- | --- | 42 | | `application/geo+json` | [Point](https://www.rfc-editor.org/rfc/rfc7946.html#section-3.1.2) | `GeoJSON` Location `Point` coordinates are displayed using [Unfolded Map 🗺️ SDK](https://docs.unfolded.ai/map-sdk/javascript-map-sdk) JavaScript library. See our [unfoldedMap.js](https://github.com/RandomFractals/unfolded-map-renderer/blob/main/src/renderer/unfoldedMap.js) for more info about that setup. | 43 | | `application/json` | Objects that contain geo location property pairs ending with: `latitude`/`longitude`, `lat/lng`, or `lat/lng`| Flat `JSON` data objects and arrays are processed by our custom [`GeoConverter`](https://github.com/RandomFractals/unfolded-map-renderer/blob/main/src/renderer/geoConverter.ts) to extract Location information and covert loaded dataset to `GeoJSON` for display on the map. | 44 | | `text/csv` | `CSV` data with column names in the 1st header row and columns ending with: `latitude`/`longitude`, `lat/lng`, or `lat/lng` | `CSV` data is parsed with [d3-dsv](https://github.com/d3/d3-dsv) JavaScript library and converted to flat `JSON` data array and then to `GeoJSON` with our [`GeoConverter`](https://github.com/RandomFractals/unfolded-map-renderer/blob/main/src/renderer/geoConverter.ts) to display locations on the map. | 45 | | `application/xml` or `text/xml` | `XML` data with root node children that contain attributes ending with: `latitude`/`longitude`, `lat/lng`, or `lat/lng` | `XML` data is parsed with [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser) to load it into `JSON` data objects array and then processed with our [`GeoConverter`](https://github.com/RandomFractals/unfolded-map-renderer/blob/main/src/renderer/geoConverter.ts) to display locations on the map. `XML` data support is very alpha and experimental at this point, and might be removed later. | 46 | | `application/vnd.code.notebook.stdout` or `text/plain` | Location data as `string` in `CSV`, `XML`, `JSON` or `GeoJSON` data format as described above | Text data typically comes from display and [`console.log()`](https://developer.mozilla.org/en-US/docs/Web/API/console/log) instructions in vscode notebooks. We try to parse text as `JSON` with [`JSON.parse()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse), as `CSV` with [d3-dsv.csvParse()](https://github.com/d3/d3-dsv#csvParse), and as `XML` with [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser). If those parse methods fail, or provided notebook cell text output contains no location data we can extract, we display text output in a custom scrollable text container with [`code pre-wrap`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/code) for a quick copy/paste to other places. Otherwise, loaded data is converted to `GeoJSON` with our [`GeoConverter`](https://github.com/RandomFractals/unfolded-map-renderer/blob/main/src/renderer/geoConverter.ts) for locations display on the map. | 47 | 48 | # 🗺️ Examples 49 | 50 | Install and use [Data Table 🈸 for Notebooks 📚](https://marketplace.visualstudio.com/items?itemName=RandomFractalsInc.vscode-data-table) built-in [Notebook 📓 Examples](https://github.com/RandomFractals/vscode-data-table#-examples) to view Unfolded Map 🗺️ with provided sample [Geo datasets](https://github.com/RandomFractals/vscode-data-table/tree/main/data). You can access built-in Data Table 🈸 Notebook 📓 Examples via `Data Table: Notebook Examples` command from `View -> Command Palette...` 51 | 52 | ![Data Table 🈸 Notebook Examples](https://github.com/RandomFractals/keplergl-notebook-renderer/blob/main/docs/images/data-table-notebook-examples.png?raw=true 53 | "Data Table 🈸 Notebook Examples") 54 | 55 | ### REST Book Example 56 | 57 | 1. Install [REST Book](https://marketplace.visualstudio.com/items?itemName=tanhakabir.rest-book) 📓 vscode extension 58 | 59 | 2. Load [World Cities](https://github.com/RandomFractals/unfolded-map-renderer/blob/main/notebooks/world-cities.restbook) REST Book 📓 60 | 61 | 3. Run All cells ⌗ 62 | 63 | 4. Click on `...` in the gutter of `GET` data output and change it to KeplerGL Map 🗺️ renderer: 64 | 65 | ![World Cities REST Book 📓](https://github.com/RandomFractals/unfolded-map-renderer/blob/main/docs/images/unfolded-map-notebook-renderer.png?raw=true 66 | "World Cities REST Book 📓") 67 | 68 | # Recommended Extensions 69 | 70 | Recommended extensions for working with Interactive Notebooks 📚 data 🈸 charts 📈 and geo 🗺️ data formats in [VSCode](https://code.visualstudio.com/): 71 | 72 | | Extension | Description | 73 | | --- | --- | 74 | | [REST Book](https://marketplace.visualstudio.com/items?itemName=tanhakabir.rest-book) | Notebook extension for running REST queries | 75 | | [TypeScript Notebooks](https://marketplace.visualstudio.com/items?itemName=donjayamanne.typescript-notebook) | TypeScript with [Jupyter](https://marketplace.visualstudio.com/items?itemName=ms-toolsai.jupyter) Notebooks 📚 | 76 | | [.NET Interactive Notebooks](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.dotnet-interactive-vscode) | .NET Interactive [Jupyter](https://marketplace.visualstudio.com/items?itemName=ms-toolsai.jupyter) Notebooks 📚 | 77 | | [Pyolite](https://marketplace.visualstudio.com/items?itemName=joyceerhl.vscode-pyolite) 🐍 | [Pyodide](https://pyodide.org) 🐍 kernel for [JupyterLite](https://github.com/jtpio/jupyterlite) Notebooks 📚 | 78 | | [Observable JS](https://marketplace.visualstudio.com/items?itemName=GordonSmith.observable-js) | Observable JS compiler with [Observable](https://observablehq.com/@observablehq/observable-for-jupyter-users?collection=@observablehq/observable-for-jupyter-users) `js` and `md` code outline and previews. | 79 | | [JS Notebook 📓 Inspector 🕵️](https://marketplace.visualstudio.com/items?itemName=RandomFractalsInc.js-notebook-inspector) | Provides Interactive Preview of [Observable JS Notebooks](https://observablehq.com/documentation#notebook-fundamentals) 📚, Notebook 📓 nodes ⎇ & cells ⌗ source code | 80 | | [Data Preivew 🈸](https://marketplace.visualstudio.com/items?itemName=RandomFractalsInc.vscode-data-preview) | Data Preview 🈸 extension for importing 📤 viewing 🔎 slicing 🔪 dicing 🎲 charting 📊 & exporting 📥 large JSON array/config, YAML, Apache Arrow, Avro & Excel data files | 81 | | [Geo Data Viewer 🗺️](https://marketplace.visualstudio.com/items?itemName=RandomFractalsInc.geo-data-viewer) | [kepler.gl](https://kepler.gl) Geo Data Analytics tool to gen. some snazzy 🗺️s w/0 `Py` 🐍 `pyWidgets` ⚙️ `pandas` 🐼 or `react` ⚛️ | 82 | | [Vega Viewer 📈](https://marketplace.visualstudio.com/items?itemName=RandomFractalsInc.vscode-vega-viewer) | Provides Interactive Preview of Vega & Vega-Lite maps 🗺️ & graphs 📈 | 83 | | [DeltaXML XPath Notebook 📓](https://marketplace.visualstudio.com/items?itemName=deltaxml.xpath-notebook) | XPath 3.1 Notebook for Visual Studio Code | 84 | | [GeoJSON Snippets](https://marketplace.visualstudio.com/items?itemName=analytic-signal.snippets-geojson) | Create geospatial objects using GeoJSON snippets | 85 | | [Data Table 🈸](https://marketplace.visualstudio.com/items?itemName=RandomFractalsInc.vscode-data-table)| Data Table 🈸 for Notebook 📓 cell ⌗ data outputs | 86 | 87 | # Dev Log 88 | 89 | See [#UnfoldedMapRenderer 🗺️ tag on Twitter](https://twitter.com/hashtag/UnfoldedMapRenderer?src=hashtag_click&f=live) for the latest and greatest updates on this vscode extension and what's in store next. 90 | 91 | # Dev Build 92 | 93 | ```bash 94 | $ git clone https://github.com/RandomFractals/unfolded-map-renderer 95 | $ cd unfolded-map-renderer 96 | $ npm install 97 | $ npm run compile 98 | $ code . 99 | ``` 100 | `F5` to launch Unfolded Map 🗺️ Renderer extension vscode debug session. 101 | 102 | || 103 | 104 | ```bash 105 | unfolded-map-renderer>vsce package 106 | ``` 107 | to generate `VSIX` Unfolded Map 🗺️ Renderer extension package with [vsce](https://code.visualstudio.com/api/working-with-extensions/publishing-extension#vsce) from our latest for local dev install in vscode. 108 | 109 | # Contributions 110 | 111 | Any and all test, code or feedback contributions are welcome. 112 | 113 | Open an [issue](https://github.com/RandomFractals/unfolded-map-renderer/issues) or create a pull request to make this Unfolded Map 🗺️ Renderer vscode extension work better for all. 114 | 115 | # Backers 116 | 117 | 118 | support me on ko-fi.com 121 | 122 | -------------------------------------------------------------------------------- /data/csv/chicago-red-light-cameras.csv: -------------------------------------------------------------------------------- 1 | Intersection,First Approach,Second Aproach,Third Approach,Go Live Date,Latitude,Longitude,Location 2 | Milwaukee-Devon,SB,WB,,02/28/2009,41.997407,-87.787921,"(41.997407, -87.787921)" 3 | California-Peterson,NB,EB,,06/29/2009,41.990442,-87.699401,"(41.990442, -87.699401)" 4 | Central-Addison,SB,EB,,11/15/2010,41.945877,-87.766754,"(41.945877, -87.766754)" 5 | Western-63rd,NB,EB,,11/12/2007,41.779214,-87.683638,"(41.779214, -87.683638)" 6 | Halsted-79th,NB,EB,,04/30/2008,41.750643,-87.644043,"(41.750643, -87.644043)" 7 | Wacker-Lake,NB,SB,,02/19/2018,41.8857,-87.637,"(41.8857, -87.637)" 8 | Laramie-Fullerton,WB,NB,,06/28/2008,41.924106,-87.756147,"(41.924106, -87.756147)" 9 | Lafayette-87th,SB,EB,,08/31/2009,41.736271,-87.625445,"(41.736271, -87.625445)" 10 | Canal-Roosevelt,NB,WB,,11/30/2008,41.867252,-87.639216,"(41.867252, -87.639216)" 11 | Pulaski-Fullerton,WB,NB,,05/19/2007,41.924484,-87.726769,"(41.924484, -87.726769)" 12 | Stony Island-Cornell-67th,NB,NB,,11/26/2007,41.77334,-87.586295,"(41.77334, -87.586295)" 13 | Western-North,NB,EB,,11/26/2007,41.91032,-87.687222,"(41.91032, -87.687222)" 14 | Cottage Grove-71st-South Chicago,NB,SB,,04/30/2008,41.765868,-87.605586,"(41.765868, -87.605586)" 15 | Wentworth-Garfield,NB,WB,,05/08/2008,41.794201,-87.630518,"(41.794201, -87.630518)" 16 | State-63rd,SB,WB,,01/18/2006,41.780058,-87.625374,"(41.780058, -87.625374)" 17 | Ashland-Division,NB,EB,,10/25/2007,41.903347,-87.667496,"(41.903347, -87.667496)" 18 | Cicero-Fullerton,SB,WB,,02/25/2006,41.924237,-87.746302,"(41.924237, -87.746302)" 19 | Cicero-Washington,NB,SB,,06/14/2008,41.881815,-87.745339,"(41.881815, -87.745339)" 20 | Sacramento-Chicago,NB,WB,,09/18/2009,41.895591,-87.702455,"(41.895591, -87.702455)" 21 | Central-Fullerton,SB,WB,,10/05/2007,41.92398,-87.765989,"(41.92398, -87.765989)" 22 | Western-Lawrence,SB,EB,,07/31/2008,41.968614,-87.688906,"(41.968614, -87.688906)" 23 | Pulaski-Irving Park,SB,WB,,05/19/2009,41.953646,-87.727617,"(41.953646, -87.727617)" 24 | Kedzie-Armitage,SB,WB,,01/23/2009,41.917402,-87.706965,"(41.917402, -87.706965)" 25 | Cicero-Diversey,NB,WB,,02/11/2010,41.931533,-87.746595,"(41.931533, -87.746595)" 26 | Milwaukee-Montrose,SB,WB,,03/11/2010,41.960632,-87.754476,"(41.960632, -87.754476)" 27 | Western-Diversey-Elston,NB,WB,,07/18/2008,41.932179,-87.687883,"(41.932179, -87.687883)" 28 | Western-Fullerton,NB,SB,,06/29/2009,41.9249,-87.687641,"(41.9249, -87.687641)" 29 | Milwaukee-Diversey,NB,EB,,06/29/2009,41.931984,-87.712251,"(41.931984, -87.712251)" 30 | Kedzie-26th,NB,SB,,11/02/2010,41.844518,-87.705042,"(41.844518, -87.705042)" 31 | Ashland-87th,SB,WB,,03/31/2007,41.735788,-87.663063,"(41.735788, -87.663063)" 32 | Pulaski-Diversey,SB,NB,,05/15/2009,41.931791,-87.726979,"(41.931791, -87.726979)" 33 | Kedzie-63rd,NB,WB,,11/26/2007,41.778972,-87.703138,"(41.778972, -87.703138)" 34 | Michigan-Ontario,SB,WB,,01/22/2018,41.893268,-87.624038,"(41.893268, -87.624038)" 35 | Western-Cermak,SB,EB,,12/29/2009,41.852031,-87.685639,"(41.852031, -87.685639)" 36 | Sheridan-Foster,SB,WB,,01/26/2008,41.976396,-87.654993,"(41.976396, -87.654993)" 37 | Pulaski-Belmont,SB,EB,,05/19/2007,41.939094,-87.727185,"(41.939094, -87.727185)" 38 | Pulaski-North,NB,WB,,11/30/2008,41.909886,-87.72633,"(41.909886, -87.72633)" 39 | Stony Island-79th-South Chicago,SB,WB,NB,05/07/2007,41.751506,-87.585823,"(41.751506, -87.585823)" 40 | Damen-63rd,NB,SB,,05/31/2008,41.779315,-87.673906,"(41.779315, -87.673906)" 41 | Cicero-North,EB,WB,,05/31/2008,41.909626,-87.746112,"(41.909626, -87.746112)" 42 | Broadway-Sheridan-Devon,SB,EB,,10/18/2007,41.99819,-87.660545,"(41.99819, -87.660545)" 43 | Kedzie-47th,NB,WB,,03/30/2008,41.808115,-87.703974,"(41.808115, -87.703974)" 44 | Pulaski-Archer-50th,EB,WB,,10/31/2007,41.802317,-87.723422,"(41.802317, -87.723422)" 45 | Elston-Lawrence,SB,WB,,06/08/2009,41.968108,-87.740163,"(41.968108, -87.740163)" 46 | Damen-Division,EB,WB,,12/29/2009,41.903191,-87.677258,"(41.903191, -87.677258)" 47 | Clark-Irving Park,EB,NB,,07/22/2008,41.954378,-87.662248,"(41.954378, -87.662248)" 48 | Ashland-71st,NB,WB,,10/11/2004,41.76491,-87.663794,"(41.76491, -87.663794)" 49 | Hamlin-Lake,NB,SB,,05/31/2008,41.885203,-87.720919,"(41.885203, -87.720919)" 50 | Austin-Irving Park,NB,EB,,06/30/2008,41.953055,-87.776775,"(41.953055, -87.776775)" 51 | Pulaski-63rd,SB,EB,,03/31/2007,41.778658,-87.722759,"(41.778658, -87.722759)" 52 | Laramie-Madison,EB,WB,,05/11/2011,41.880371,-87.755065,"(41.880371, -87.755065)" 53 | Osceola-Touhy,EB,WB,,10/21/2008,42.011553,-87.812251,"(42.011553, -87.812251)" 54 | Pulaski-Armitage,WB,EB,,05/31/2008,41.917165,-87.726559,"(41.917165, -87.726559)" 55 | California-Devon,NB,EB,,07/31/2008,41.997559,-87.699643,"(41.997559, -87.699643)" 56 | Pulaski-Chicago,SB,EB,,02/20/2010,41.895367,-87.726078,"(41.895367, -87.726078)" 57 | Damen-Elston,SB,,,02/17/2006,41.925816,-87.677898,"(41.925816, -87.677898)" 58 | Western-Madison,NB,WB,,06/01/2004,41.881161,-87.686432,"(41.881161, -87.686432)" 59 | Dr Martin Luther King-31st,NB,EB,,06/22/2008,41.838419,-87.617465,"(41.838419, -87.617465)" 60 | Pulaski-Roosevelt,NB,WB,,07/17/2009,41.866172,-87.725169,"(41.866172, -87.725169)" 61 | Ashland-95th,SB,EB,,06/26/2009,41.721214,-87.662684,"(41.721214, -87.662684)" 62 | Halsted-95th,NB,SB,,04/30/2008,41.721458,-87.643212,"(41.721458, -87.643212)" 63 | Damen-Diversey-Clybourn,SB,WB,,06/30/2008,41.932285,-87.678136,"(41.932285, -87.678136)" 64 | Pulaski-Division,NB,SB,,07/22/2009,41.902671,-87.726303,"(41.902671, -87.726303)" 65 | Kostner-Grand-North,EB,NB,SB,03/11/2004,41.909754,-87.736262,"(41.909754, -87.736262)" 66 | Western-Addison,NB,EB,,06/08/2009,41.946731,-87.688258,"(41.946731, -87.688258)" 67 | Cicero-47th,SB,WB,,03/31/2008,41.807623,-87.743153,"(41.807623, -87.743153)" 68 | Hamlin-Madison,NB,EB,,04/29/2009,41.880789,-87.720752,"(41.880789, -87.720752)" 69 | Michigan-Jackson,NB,EB,,01/22/2018,41.878246,-87.624087,"(41.878246, -87.624087)" 70 | Sheridan-Hollywood,WB,EB,,10/18/2007,41.985549,-87.655242,"(41.985549, -87.655242)" 71 | Northwest Hwy-Foster,SEB,EB,,09/29/2017,41.975688,-87.769261,"(41.975688, -87.769261)" 72 | Halsted-99th,NB,EB,,01/01/2006,41.714215,-87.643004,"(41.714215, -87.643004)" 73 | Cicero-Armitage,EB,NB,,11/14/2008,41.916931,-87.746111,"(41.916931, -87.746111)" 74 | Ashland-Lawrence,SB,EB,,08/27/2008,41.968876,-87.66944,"(41.968876, -87.66944)" 75 | LaSalle-Kinzie,NB,EB,,04/30/2004,41.889187,-87.632526,"(41.889187, -87.632526)" 76 | Western-Chicago,NB,EB,,05/07/2007,41.895743,-87.686843,"(41.895743, -87.686843)" 77 | Austin-Addison,EB,NB,,06/28/2008,41.945771,-87.776504,"(41.945771, -87.776504)" 78 | Halsted-Division,NB,WB,,04/07/2004,41.903636,-87.648094,"(41.903636, -87.648094)" 79 | Halsted-111th,SB,WB,,01/01/2006,41.692355,-87.642377,"(41.692355, -87.642377)" 80 | Lake Shore-Belmont,SB,EB,,06/22/2008,41.94024,-87.638696,"(41.94024, -87.638696)" 81 | Western-79th,NB,WB,,05/07/2007,41.750101,-87.682847,"(41.750101, -87.682847)" 82 | Western-47th,SB,NB,,11/29/2004,41.808426,-87.684425,"(41.808426, -87.684425)" 83 | Pulaski-Lawrence,SB,EB,,07/31/2008,41.968242,-87.728027,"(41.968242, -87.728027)" 84 | Western-55th,SB,EB,,11/01/2003,41.793877,-87.68404,"(41.793877, -87.68404)" 85 | Kedzie-71st,SB,WB,,09/17/2009,41.76439,-87.702811,"(41.76439, -87.702811)" 86 | Cicero-Peterson,SB,WB,,08/26/2008,41.989898,-87.748325,"(41.989898, -87.748325)" 87 | California-Irving Park,WB,EB,,08/26/2008,41.953973,-87.69824,"(41.953973, -87.69824)" 88 | Clark-Fullerton,NB,SB,,06/27/2007,41.925585,-87.64048,"(41.925585, -87.64048)" 89 | Cicero-Harrison,SB,EB,,11/19/2009,41.873141,-87.745,"(41.873141, -87.745)" 90 | Western-Van Buren,WB,SB,,05/29/2008,41.876083,-87.686271,"(41.876083, -87.686271)" 91 | Harlem-Belmont,NB,WB,,06/18/2007,41.937997,-87.806746,"(41.937997, -87.806746)" 92 | Western-Touhy,SB,NB,,10/21/2008,42.012279,-87.690246,"(42.012279, -87.690246)" 93 | Narragansett-Irving Park,EB,WB,,10/14/2004,41.952916,-87.786558,"(41.952916, -87.786558)" 94 | Ashland-Cortland,NB,EB,,02/26/2006,41.916128,-87.6678,"(41.916128, -87.6678)" 95 | Central-Diversey,SB,WB,,08/18/2009,41.931278,-87.766248,"(41.931278, -87.766248)" 96 | Western-Foster,SB,WB,,06/05/2007,41.97589,-87.689148,"(41.97589, -87.689148)" 97 | Vincennes-87th,SB,EB,,11/11/2004,41.73605,-87.645174,"(41.73605, -87.645174)" 98 | Kilpatrick-Irving Park,EB,WB,,10/21/2008,41.953446,-87.745578,"(41.953446, -87.745578)" 99 | Kedzie-Belmont,SB,EB,NB,03/01/2004,41.93933,-87.707696,"(41.93933, -87.707696)" 100 | Cicero-Lawrence,NB,SB,,11/02/2004,41.968029,-87.74772,"(41.968029, -87.74772)" 101 | Central-Chicago,SB,EB,,05/28/2010,41.894852,-87.765395,"(41.894852, -87.765395)" 102 | Kedzie-79th-Columbus,SB,EB,,01/10/2006,41.749842,-87.702396,"(41.749842, -87.702396)" 103 | Kedzie-31st,SB,WB,,05/23/2008,41.837231,-87.704823,"(41.837231, -87.704823)" 104 | Ashland-Fullerton,NB,SB,,06/08/2009,41.92515,-87.668144,"(41.92515, -87.668144)" 105 | Damen-Fullerton,EB,,,02/17/2006,41.925025,-87.677898,"(41.925025, -87.677898)" 106 | Central-Belmont,SB,WB,,02/05/2009,41.938573,-87.766499,"(41.938573, -87.766499)" 107 | Clark-Chicago,EB,WB,,10/22/2010,41.896635,-87.631243,"(41.896635, -87.631243)" 108 | Elston-Addison,SB,EB,,10/19/2007,41.946622,-87.708841,"(41.946622, -87.708841)" 109 | Kostner-Roosevelt,EB,NB,,03/18/2004,41.866031,-87.734965,"(41.866031, -87.734965)" 110 | Sacramento-Lake,NB,SB,,10/20/2009,41.884075,-87.701291,"(41.884075, -87.701291)" 111 | Stony Island-76th,NB,SB,,11/30/2008,41.756944,-87.58609,"(41.756944, -87.58609)" 112 | Austin-Diversey,WB,EB,,06/28/2008,41.931139,-87.775966,"(41.931139, -87.775966)" 113 | Western-Devon,NB,SB,,07/31/2008,41.99773,-87.689881,"(41.99773, -87.689881)" 114 | Halsted-Roosevelt,WB,EB,,06/14/2008,41.867152,-87.646919,"(41.867152, -87.646919)" 115 | Halsted-Fullerton-Lincoln,NB,WB,,08/31/2008,41.925454,-87.64876,"(41.925454, -87.64876)" 116 | State-75th,NB,WB,,08/28/2009,41.75818,-87.624757,"(41.75818, -87.624757)" 117 | Central-Lake,SB,EB,,07/17/2009,41.887729,-87.76512,"(41.887729, -87.76512)" 118 | Ashland-Madison,NB,WB,,03/06/2004,41.881454,-87.666802,"(41.881454, -87.666802)" 119 | Narragansett-Fullerton,EB,WB,,11/14/2008,41.923676,-87.785441,"(41.923676, -87.785441)" 120 | Nagle-Foster,WB,NB,,10/14/2004,41.975652,-87.787872,"(41.975652, -87.787872)" 121 | Cicero-Archer,NB,WB,,11/13/2007,41.798659,-87.742927,"(41.798659, -87.742927)" 122 | California-Diversey,NB,WB,EB,01/31/2006,41.932096,-87.697616,"(41.932096, -87.697616)" 123 | Laramie-Irving Park,EB,WB,,01/27/2010,41.953299,-87.757148,"(41.953299, -87.757148)" 124 | Elston-Irving Park,SB,EB,,08/12/2009,41.95373,-87.719084,"(41.95373, -87.719084)" 125 | Western-Peterson,NB,SB,,02/26/2004,41.9905,-87.689671,"(41.9905, -87.689671)" 126 | Kedzie-55th,SB,EB,,10/20/2009,41.793513,-87.703553,"(41.793513, -87.703553)" 127 | Pulaski-Cermak,SB,WB,,10/11/2004,41.851546,-87.724757,"(41.851546, -87.724757)" 128 | Ashland-Irving Park,NB,EB,,08/26/2008,41.954291,-87.669047,"(41.954291, -87.669047)" 129 | Western-Marquette,SB,WB,,11/30/2008,41.771977,-87.683443,"(41.771977, -87.683443)" 130 | Halsted-North,NB,WB,,06/29/2009,41.91092,-87.648273,"(41.91092, -87.648273)" 131 | Central-Irving Park,SB,EB,,06/30/2008,41.953183,-87.766998,"(41.953183, -87.766998)" 132 | Pulaski-79th,SB,WB,,09/17/2009,41.749569,-87.721913,"(41.749569, -87.721913)" 133 | Pulaski-Foster,SB,WB,,10/18/2007,41.975532,-87.728234,"(41.975532, -87.728234)" 134 | Cicero-Chicago,NB,EB,,10/05/2007,41.895003,-87.745805,"(41.895003, -87.745805)" 135 | Illinois-Columbus,NB,SB,,10/28/2010,41.891002,-87.620224,"(41.891002, -87.620224)" 136 | Central-Milwaukee,SB,SEB,,09/29/2017,41.976514,-87.768467,"(41.976514, -87.768467)" 137 | State-79th,WB,NB,,06/26/2009,41.750958,-87.624547,"(41.750958, -87.624547)" 138 | Kostner-Ogden,SB,EB,,05/23/2008,41.847697,-87.734387,"(41.847697, -87.734387)" 139 | Clark-Ridge,NB,SB,,07/23/2008,41.989697,-87.669985,"(41.989697, -87.669985)" 140 | Pulaski-55th,SB,WB,,11/19/2004,41.793205,-87.72316,"(41.793205, -87.72316)" 141 | Western-Montrose,NB,WB,,08/26/2008,41.961313,-87.688681,"(41.961313, -87.688681)" 142 | Jeffery-95th,SB,EB,,11/26/2007,41.722468,-87.575353,"(41.722468, -87.575353)" 143 | Halsted-Madison,NB,SB,,06/14/2008,41.881776,-87.647361,"(41.881776, -87.647361)" 144 | Broadway-Foster,NB,EB,,10/18/2007,41.976323,-87.659867,"(41.976323, -87.659867)" 145 | Homan-Kimball-North,NB,EB,,10/05/2007,41.910053,-87.711879,"(41.910053, -87.711879)" 146 | Western-35th,SB,NB,,10/11/2004,41.83028,-87.685033,"(41.83028, -87.685033)" 147 | Halsted-119th,SB,WB,,11/02/2004,41.677815,-87.641907,"(41.677815, -87.641907)" 148 | Cicero-Addison,NB,SB,,11/30/2008,41.946124,-87.747064,"(41.946124, -87.747064)" 149 | Harlem-Addison,NB,EB,,06/21/2009,41.945264,-87.807006,"(41.945264, -87.807006)" 150 | Cicero-Stevenson NB (SOUTH INTERSECTION),NB,SB,,04/29/2009,41.817092,-87.743477,"(41.817092, -87.743477)" 151 | -------------------------------------------------------------------------------- /data/csv/usa-state-capitals.csv: -------------------------------------------------------------------------------- 1 | State,ST,Capital,Longitude,Latitude 2 | Alabama,AL,Montgomery,-86.300280684889,32.3778448300578 3 | Alaska,AK,Juneau,-134.419720089079,58.3019435628538 4 | Arizona,AZ,Phoenix,-112.097002114648,33.448056962118 5 | Arkansas,AR,Little Rock,-92.2891966155731,34.74671389912 6 | California,CA,Sacramento,-121.493173407028,38.5766379822497 7 | Colorado,CO,Denver,-104.984882535635,39.7393011782883 8 | Connecticut,CT,Hartford,-72.682265685282,41.7640478075494 9 | Delaware,DE,Dover,-75.521440669349,39.1598182563424 10 | Florida,FL,Tallahassee,-84.2814103124204,30.4379800379088 11 | Georgia,GA,Atlanta,-84.3882728102467,33.7491105069311 12 | Hawaii,HI,Honolulu,-157.857644685749,21.3071891251897 13 | Idaho,ID,Boise,-116.200071549668,43.6173976205726 14 | Illinois,IL,Springfield,-89.6838561293087,39.7992266437577 15 | Indiana,IN,Indianapolis,-86.1619162318749,39.7682876590079 16 | Iowa,IA,Des Moines,-93.6038299676467,41.591203450586 17 | Kansas,KS,Topeka,-95.6781165783569,39.0481868390344 18 | Kentucky,KY,Frankfort,-84.8752029177421,38.1868295579102 19 | Louisiana,LA,Baton Rouge,-91.1873435440524,30.4561959742174 20 | Maine,ME,Augusta,-69.7824740545278,44.3068311917176 21 | Maryland,MD,Annapolis,-76.490730353326,38.9788809750953 22 | Massachusetts,MA,Boston,-71.0635920009677,42.3585156598684 23 | Michigan,MI,Lansing,-84.5554894724477,42.7337559214066 24 | Minnesota,MN,St. Paul,-93.1023668129999,44.9544483754758 25 | Mississippi,MS,Jackson,-90.1821570985857,32.3038596464079 26 | Missouri,MO,Jefferson City,-92.1729471612446,38.5792342520804 27 | Montana,MT,Helena,-112.017030200267,46.5844748792441 28 | Nebraska,NE,Lincoln,-96.6997323196763,40.8080846893224 29 | Nevada,NV,Carson City,-119.765996538968,39.1639658818133 30 | New Hampshire,NH,Concord,-71.5360412913525,43.2077286653951 31 | New Jersey,NJ,Trenton,-74.7701082395055,40.2205925416604 32 | New Mexico,NM,Santa Fe,-105.939263846866,35.682385674315 33 | New York,NY,Albany,-73.7584566763079,42.6531923942429 34 | North Carolina,NC,Raleigh,-78.6390536727153,35.7808620976202 35 | North Dakota,ND,Bismarck,-100.782425301832,46.8204800624107 36 | Ohio,OH,Columbus,-83.000216483074,39.9611972655304 37 | Oklahoma,OK,Oklahoma City,-97.5033086417702,35.4930913156566 38 | Oregon,OR,Salem,-123.030608818409,44.9383658965847 39 | Pennsylvania,PA,Harrisburg,-76.8841110484574,40.2651554758888 40 | Rhode Island,RI,Providence,-71.4150694021695,41.8304368543275 41 | South Carolina,SC,Columbia,-81.033361075349,34.0006222412432 42 | South Dakota,SD,Pierre,-100.345546329203,44.3671499721808 43 | Tennessee,TN,Nashville,-86.7844011981955,36.1658136639888 44 | Texas,TX,Austin,-97.7403787162921,30.2746490151032 45 | Utah,UT,Salt Lake City,-111.888143519988,40.7765189566751 46 | Vermont,VT,Montpelier,-72.5804431413164,44.2619812631813 47 | Virginia,VA,Richmond,-77.4334960632491,37.5387725441582 48 | Washington,WA,Olympia,-122.904762637417,47.0362418589047 49 | West Virginia,WV,Charleston,-81.6126542355569,38.3363786775331 50 | Wisconsin,WI,Madison,-89.384196048713,43.0752429469311 51 | Wyoming,WY,Cheyenne,-104.820410067003,41.1407764260928 -------------------------------------------------------------------------------- /data/csv/world-countries.csv: -------------------------------------------------------------------------------- 1 | longitude,latitude,COUNTRY,ISO,COUNTRYAFF,AFF_ISO 2 | -170.7007316174498,-14.305711987770538,American Samoa,AS,United States,US 3 | -61.98493557207482,15.421124215614471,United States Minor Outlying Islands,UM,United States,US 4 | -161.46513330483654,-17.435370030130244,Cook Islands,CK,New Zealand,NZ 5 | -145.255376012188,-13.526316739606633,French Polynesia,PF,France,FR 6 | -169.86878106699083,-19.05230921680393,Niue,NU,New Zealand,NZ 7 | -129.0334897679429,-24.653806919025705,Pitcairn,PN,United Kingdom,GB 8 | -172.14588210018303,-13.760751252387802,Samoa,WS,Samoa,WS 9 | -171.85265950722743,-9.195174767256544,Tokelau,TK,New Zealand,NZ 10 | -174.6821765193416,-20.059250935052873,Tonga,TO,Tonga,TO 11 | -177.16299992783053,-13.792571994599982,Wallis and Futuna,WF,France,FR 12 | -88.85911489238985,13.758041517055418,El Salvador,SV,El Salvador,SV 13 | -90.31219349119617,15.820878515352684,Guatemala,GT,Guatemala,GT 14 | -103.12043937176708,23.64394843426795,Mexico,MX,Mexico,MX 15 | -93.56663466105805,62.3658719808934,Canada,CA,Canada,CA 16 | -64.44315167435285,-37.60564452525247,Argentina,AR,Argentina,AR 17 | -59.51781251542691,-51.75209043005578,Falkland Islands,FK,United Kingdom,GB 18 | -81.25545034464567,-34.32823756130027,Chile,CL,Chile,CL 19 | -82.33897595908059,-1.2980654335322974,Ecuador,EC,Ecuador,EC 20 | -74.11416196781884,-8.522717984240291,Peru,PE,Peru,PE 21 | -64.45209597511206,-16.7312488393574,Bolivia,BO,Bolivia,BO 22 | -54.355206608256424,-11.524630416426652,Brazil,BR,Brazil,BR 23 | -58.38906357428651,-23.42190559259428,Paraguay,PY,Paraguay,PY 24 | -56.01919523458085,-32.78195043831093,Uruguay,UY,Uruguay,UY 25 | -33.084862315910726,-55.79467861523634,South Georgia and South Sandwich Islands,GS,United Kingdom,GB 26 | -173.95712216184216,-76.48551363834154,Antarctica,AQ,Antarctica,AQ 27 | 178.6951729153761,-17.62052426700569,Fiji,FJ,Fiji,FJ 28 | -5.717391620813109,-15.962963318340398,Saint Helena,SH,United Kingdom,GB 29 | -63.06008343771806,18.222874004219086,Anguilla,AI,United Kingdom,GB 30 | -61.79187002978877,17.32188358622719,Antigua and Barbuda,AG,Antigua and Barbuda,AG 31 | -69.97564014284046,12.515625722992898,Aruba,AW,Aruba,AW 32 | -75.94757049263755,23.971980844721568,Bahamas,BS,Bahamas,BS 33 | -59.557383949150285,13.183219369337529,Barbados,BB,Barbados,BB 34 | -88.5802147985989,17.29459368926392,Belize,BZ,Belize,BZ 35 | -64.7458500599169,32.315067430740726,Bermuda,BM,United Kingdom,GB 36 | -68.29350445958761,12.180844982440338,Bonaire,BQ,Netherlands,NL 37 | -64.51741866359077,18.446627982858313,British Virgin Islands,VG,United Kingdom,GB 38 | -81.25203208977878,19.311231805620288,Cayman Islands,KY,United Kingdom,GB 39 | -73.84582517707032,5.294234610435874,Colombia,CO,Colombia,CO 40 | -84.14673625701816,9.863467407406214,Costa Rica,CR,Costa Rica,CR 41 | -79.6459652585029,21.50036820995566,Cuba,CU,Cuba,CU 42 | -68.96939768599042,12.199996647939832,Curacao,CW,Netherlands,NL 43 | -61.360471946942994,15.429269860940513,Dominica,DM,Dominica,DM 44 | -70.40475973716906,18.75542599628316,Dominican Republic,DO,Dominican Republic,DO 45 | -53.32232307156624,3.857429742497078,French Guiana,GF,France,FR 46 | -61.67937937204098,12.112926656338907,Grenada,GD,Grenada,GD 47 | -61.47999931489154,16.16880154346758,Guadeloupe,GP,France,FR 48 | -58.91352612754667,4.68211981385056,Guyana,GY,Guyana,GY 49 | -72.88622713826513,18.911768634685547,Haiti,HT,Haiti,HT 50 | -86.48189284585226,14.814433611247111,Honduras,HN,Honduras,HN 51 | -77.30358894542778,18.12207889341651,Jamaica,JM,Jamaica,JM 52 | -61.01432380875083,14.642697353597645,Martinique,MQ,France,FR 53 | -62.18693281256255,16.735363391460357,Montserrat,MS,United Kingdom,GB 54 | -85.016088327669,12.893566631930554,Nicaragua,NI,Nicaragua,NI 55 | -80.17590175543056,8.422311846143703,Panama,PA,Panama,PA 56 | -66.41658843324701,18.210417890187674,Puerto Rico,PR,United States,US 57 | -63.23739481909494,17.632512616389718,Saba,BQ,Netherlands,NL 58 | -62.83051610005156,17.90561691241738,Saint Barthelemy,BL,France,FR 59 | -62.978230589445026,17.4919042294197,Saint Eustatius,BQ,Netherlands,NL 60 | -62.74560385895787,17.314736299587768,Saint Kitts and Nevis,KN,Saint Kitts and Nevis,KN 61 | -60.9689510935251,13.895749185129906,Saint Lucia,LC,Saint Lucia,LC 62 | -63.06678525361946,18.078012113224464,Saint Martin,MF,France,FR 63 | -56.293775131873765,46.916907230538186,Saint Pierre and Miquelon,PM,France,FR 64 | -61.193766354393034,13.254808122970651,Saint Vincent and the Grenadines,VC,Saint Vincent and the Grenadines,VC 65 | -63.06883135915303,18.03942608463078,Sint Maarten,SX,Netherlands,NL 66 | -55.855514311561286,4.098723595920171,Suriname,SR,Suriname,SR 67 | -61.219702159991385,10.580055762974936,Trinidad and Tobago,TT,Trinidad and Tobago,TT 68 | -71.58749619781581,21.714564146976688,Turks and Caicos Islands,TC,United Kingdom,GB 69 | -64.82237229469811,17.997411702882236,US Virgin Islands,VI,United States,US 70 | -66.36112352700972,7.162820597836788,Venezuela,VE,Venezuela,VE 71 | -1.6932816211842325,12.108709036312737,Burkina Faso,BF,Burkina Faso,BF 72 | -23.967443137094858,16.068302102903527,Cabo Verde,CV,Cabo Verde,CV 73 | -5.571710194917734,7.536779279421307,Côte d'Ivoire,CI,Côte d'Ivoire,CI 74 | -15.383380385869662,13.428617959189328,Gambia,GM,Gambia,GM 75 | -1.219233362526581,7.94530467243628,Ghana,GH,Ghana,GH 76 | -5.345549484594358,36.14022671336082,Gibraltar,GI,United Kingdom,GB 77 | -10.986948848040218,10.255986541378112,Guinea,GN,Guinea,GN 78 | -15.15305969813266,11.890510055620117,Guinea-Bissau,GW,Guinea-Bissau,GW 79 | -9.258988935497618,6.52012979398834,Liberia,LR,Liberia,LR 80 | -4.346399841781153,17.168146208584837,Mali,ML,Mali,ML 81 | -10.495079045035716,20.466731212820022,Mauritania,MR,Mauritania,MR 82 | -8.817212587250811,28.687598134979325,Morocco,MA,Morocco,MA 83 | -16.832656931059564,38.020288343746714,Portugal,PT,Portugal,PT 84 | -14.610875368352305,14.228861491763402,Senegal,SN,Senegal,SN 85 | -11.808781566553495,8.543593293153963,Sierra Leone,SL,Sierra Leone,SL 86 | -42.18679364299874,74.14793601519504,Greenland,GL,Denmark,DK 87 | -2.576392582891568,49.45870771378872,Guernsey,GG,United Kingdom,GB 88 | -8.258826761874563,53.30614676207018,Ireland,IE,Ireland,IE 89 | -4.532995055468449,54.22855301008011,Isle of Man,IM,United Kingdom,GB 90 | -2.1291601162653575,49.215396925724306,Jersey,JE,United Kingdom,GB 91 | -3.156995563222747,54.90083227861851,United Kingdom,GB,United Kingdom,GB 92 | -19.05682967106099,65.12360920205514,Iceland,IS,Iceland,IS 93 | -6.852020428963805,61.97101453244277,Faroe Islands,FO,Denmark,DK 94 | 13.36016331611152,76.48564398291828,Svalbard,SJ,Norway,NO 95 | 3.411969465057627,-54.42316679395248,Bouvet Island,BV,Norway,NO 96 | 56.86665418117432,-43.65747884581795,New Zealand,NZ,New Zealand,NZ 97 | 17.478008046252885,-11.89758947644664,Angola,AO,Angola,AO 98 | 23.85779956995608,-22.236609002062902,Botswana,BW,Botswana,BW 99 | 29.88518227845293,-3.261251993278643,Burundi,BI,Burundi,BI 100 | 43.81817519272116,-11.969445595220847,Comoros,KM,Comoros,KM 101 | 14.879732849491393,-0.7294391595233845,Congo,CG,Congo,CG 102 | 23.419827574282188,-3.338629596207896,Congo DRC,CD,Congo DRC,CD 103 | 11.839410898545754,-0.628448459921234,Gabon,GA,Gabon,GA 104 | 37.95309411262371,0.6899182318376179,Kenya,KE,Kenya,KE 105 | 28.24475317864227,-29.60168116924817,Lesotho,LS,Lesotho,LS 106 | 34.23441182298881,-13.128986464184024,Malawi,MW,Malawi,MW 107 | 42.74374761089645,-17.06449193630804,Juan De Nova Island,TF,France,FR 108 | 35.208577031290176,-17.525230309488748,Mozambique,MZ,Mozambique,MZ 109 | 18.16451345845268,-21.90858163281473,Namibia,NA,Namibia,NA 110 | 29.919439681764082,-2.014687460047154,Rwanda,RW,Rwanda,RW 111 | 6.911986724638052,0.7728330713558265,Sao Tome and Principe,ST,Sao Tome and Principe,ST 112 | 27.578231339253033,-32.72976617311268,South Africa,ZA,South Africa,ZA 113 | 31.510685746082007,-26.562540935608702,Eswatini,SZ,Eswatini,SZ 114 | 34.93574264768485,-6.35360420423765,Tanzania,TZ,Tanzania,TZ 115 | 27.75521363430896,-13.162832953186246,Zambia,ZM,Zambia,ZM 116 | 29.717829640720844,-18.92700121981475,Zimbabwe,ZW,Zimbabwe,ZW 117 | 72.43501618476016,-7.323548444385743,British Indian Ocean Territory,IO,United Kingdom,GB 118 | 63.297413102060936,-48.26579567146711,French Southern Territories,TF,France,FR 119 | 73.49298560844045,-53.084170035513736,Heard Island and McDonald Islands,HM,Australia,AU 120 | 46.68493466832544,-19.04163612493041,Madagascar,MG,Madagascar,MG 121 | 59.68861271868012,-20.06050170376338,Mauritius,MU,Mauritius,MU 122 | 45.14867383883924,-12.821449995165704,Mayotte,YT,France,FR 123 | 47.290948081543384,-11.566224871643417,Glorioso Islands,TF,France,FR 124 | 55.54393506194689,-21.119825460665105,Réunion,RE,France,FR 125 | 51.28904175365966,-6.847341132139227,Seychelles,SC,Seychelles,SC 126 | 2.6558464719769135,28.350969744889056,Algeria,DZ,Algeria,DZ 127 | 2.305714528830206,9.503013199615893,Benin,BJ,Benin,BJ 128 | 12.948474142398263,6.294168487480992,Cameroon,CM,Cameroon,CM 129 | 20.520743419397256,6.331390033944319,Central African Republic,CF,Central African Republic,CF 130 | 18.427113900363025,15.283493546654503,Chad,TD,Chad,TD 131 | 9.917747921680592,2.1634530114884796,Equatorial Guinea,GQ,Equatorial Guinea,GQ 132 | -42.29462747902002,1.6860774162119534,Kiribati,KI,Kiribati,KI 133 | 17.91133392454237,27.202915771690794,Libya,LY,Libya,LY 134 | 14.441922442508494,35.890522650899314,Malta,MT,Malta,MT 135 | 8.86863247002646,17.08105392407292,Niger,NE,Niger,NE 136 | 8.147632718717043,9.609707376481591,Nigeria,NG,Nigeria,NG 137 | 0.8990857571109684,8.660743037717811,Togo,TG,Togo,TG 138 | 9.65587551697984,34.08636179565723,Tunisia,TN,Tunisia,TN 139 | 33.375346009199205,35.11700416345239,Cyprus,CY,Cyprus,CY 140 | 42.613496898789506,11.750235727618804,Djibouti,DJ,Djibouti,DJ 141 | 30.240135435012338,26.60517034450628,Egypt,EG,Egypt,EG 142 | 39.2672401449901,15.005533147667684,Eritrea,ER,Eritrea,ER 143 | 39.914902886544276,8.729389557048396,Ethiopia,ET,Ethiopia,ET 144 | 24.255596388632085,38.41864937016185,Greece,GR,Greece,GR 145 | 43.832529181056884,33.105075667527906,Iraq,IQ,Iraq,IQ 146 | 35.027923472437024,31.513542220043195,Israel,IL,Israel,IL 147 | 36.95728884547246,31.387064884449156,Jordan,JO,Jordan,JO 148 | 35.89651946324749,33.91160170722086,Lebanon,LB,Lebanon,LB 149 | 35.03083098563104,31.820828421158886,Palestinian Territory,PS,Palestinian Territory,PS 150 | 30.3851856901788,7.657782041763295,South Sudan,SS,South Sudan,SS 151 | 29.951458283594064,15.67060230984256,Sudan,SD,Sudan,SD 152 | 38.5117323139514,35.09751106058316,Syria,SY,Syria,SY 153 | 35.09557205928997,39.09097225284415,Turkey,TR,Turkey,TR 154 | 32.34371768463123,1.2821729218416205,Uganda,UG,Uganda,UG 155 | 1.5802243611232873,42.54859834854764,Andorra,AD,Andorra,AD 156 | -127.76385744090393,42.46427186904937,United States,US,United States,US 157 | 2.936178131958199,46.20410930340389,France,FR,France,FR 158 | 9.547674672376376,47.14627562133036,Liechtenstein,LI,Liechtenstein,LI 159 | 7.412820873271196,43.74798224995656,Monaco,MC,Monaco,MC 160 | 8.286928794895285,46.73678128684938,Switzerland,CH,Switzerland,CH 161 | 4.675010154696485,50.6182138854095,Belgium,BE,Belgium,BE 162 | 10.46159124903506,51.14928158531881,Germany,DE,Germany,DE 163 | 6.103230338458876,49.77523454542369,Luxembourg,LU,Luxembourg,LU 164 | 5.4745768526275995,52.13751518539507,Netherlands,NL,Netherlands,NL 165 | 20.061082767269493,41.14165894891656,Albania,AL,Albania,AL 166 | 13.797778364631036,47.631858269895794,Austria,AT,Austria,AT 167 | 17.83467240787538,44.14415356126429,Bosnia and Herzegovina,BA,Bosnia and Herzegovina,BA 168 | 16.782818411227737,44.64931472195953,Croatia,HR,Croatia,HR 169 | 15.383273292023533,49.74917370930982,Czech Republic,CZ,Czech Republic,CZ 170 | 11.00211247600492,55.91555312652204,Denmark,DK,Denmark,DK 171 | 19.39620048366142,47.22527332486294,Hungary,HU,Hungary,HU 172 | 12.246695926942852,41.99599184660806,Italy,IT,Italy,IT 173 | 19.29505087156758,42.73694835210454,Montenegro,ME,Montenegro,ME 174 | 19.43573279234468,52.06848055692473,Poland,PL,Poland,PL 175 | 12.461278349581722,43.942820729097896,San Marino,SM,San Marino,SM 176 | 20.85677444395745,44.02679870131969,Serbia,RS,Serbia,RS 177 | 19.581015362490966,48.69808390520484,Slovakia,SK,Slovakia,SK 178 | 14.890636899973781,46.13759229564504,Slovenia,SI,Slovenia,SI 179 | 21.70998923872772,41.59402890143112,North Macedonia,MK,North Macedonia,MK 180 | 12.451312917026133,41.90402351316735,Vatican City,VA,Vatican City,VA 181 | 16.463696137046043,65.18711088537542,Norway,NO,Norway,NO 182 | 17.277289833215,62.46541151205906,Sweden,SE,Sweden,SE 183 | 27.964252054715104,53.46791374543163,Belarus,BY,Belarus,BY 184 | 25.251739122561908,42.82043677302438,Bulgaria,BG,Bulgaria,BG 185 | 25.23640542437383,58.57756953800766,Estonia,EE,Estonia,EE 186 | 25.196596380195327,64.81356381018371,Finland,FI,Finland,FI 187 | 43.378866534112234,42.17986277737226,Georgia,GE,Georgia,GE 188 | 24.693671325654403,56.813853047554154,Latvia,LV,Latvia,LV 189 | 23.889370978174423,55.28904028365277,Lithuania,LT,Lithuania,LT 190 | 28.391111865941348,47.0725674580696,Moldova,MD,Moldova,MD 191 | 25.094158201563292,45.82454894397586,Romania,RO,Romania,RO 192 | 31.27377208442636,48.657532515563794,Ukraine,UA,Ukraine,UA 193 | 66.59216131095278,34.13402601376932,Afghanistan,AF,Afghanistan,AF 194 | 50.62094026880333,25.964434666686603,Bahrain,BH,Bahrain,BH 195 | 82.83375236985977,20.688393643630018,India,IN,India,IN 196 | 54.237077001065444,32.906023742890056,Iran,IR,Iran,IR 197 | 47.631413840209895,29.306571941224693,Kuwait,KW,Kuwait,KW 198 | 73.23878260570868,3.2391153839409266,Maldives,MV,Maldives,MV 199 | 84.1338898313567,28.300920699755657,Nepal,NP,Nepal,NP 200 | 55.89703043777166,21.080814680695312,Oman,OM,Oman,OM 201 | 69.08835090769651,30.116188371410882,Pakistan,PK,Pakistan,PK 202 | 51.19794918743203,25.318528486425386,Qatar,QA,Qatar,QA 203 | 44.54714296861613,24.075476084830914,Saudi Arabia,SA,Saudi Arabia,SA 204 | 45.40037867243972,6.524534573103924,Somalia,SO,Somalia,SO 205 | 80.65376391290388,7.719586213734208,Sri Lanka,LK,Sri Lanka,LK 206 | 70.94215281065698,38.56933138382972,Tajikistan,TJ,Tajikistan,TJ 207 | 58.4577357627054,39.06069118001429,Turkmenistan,TM,Turkmenistan,TM 208 | 54.27920525789581,24.18250292309135,United Arab Emirates,AE,United Arab Emirates,AE 209 | 48.471214933713796,15.250598269139491,Yemen,YE,Yemen,YE 210 | 45.05490831965259,40.17841274230679,Armenia,AM,Armenia,AM 211 | 48.39830514333845,40.33497634263672,Azerbaijan,AZ,Azerbaijan,AZ 212 | 66.3759193479301,47.641465195176835,Kazakhstan,KZ,Kazakhstan,KZ 213 | 74.17532903468319,41.35698905438358,Kyrgyzstan,KG,Kyrgyzstan,KG 214 | 63.8548297593985,41.4879065244633,Uzbekistan,UZ,Uzbekistan,UZ 215 | 105.70209512200549,-10.446440802183416,Christmas Island,CX,Australia,AU 216 | 96.83688767323002,-12.171249450199545,Cocos Islands,CC,Australia,AU 217 | 118.73586057233209,-2.3079333544632434,Indonesia,ID,Indonesia,ID 218 | 125.66817397782899,-8.798839646941667,Timor-Leste,TL,Timor-Leste,TL 219 | 137.11656434074948,-30.134160279858374,Australia,AU,Australia,AU 220 | 166.92937633139178,-0.5221021440668993,Nauru,NR,Nauru,NR 221 | 166.27594499606235,-21.253890348985426,New Caledonia,NC,France,FR 222 | 167.95259597483337,-29.037654445046282,Norfolk Island,NF,Australia,AU 223 | 148.1803959140757,-6.430015996626476,Papua New Guinea,PG,Papua New Guinea,PG 224 | 160.96663461713925,-9.760237065778515,Solomon Islands,SB,Solomon Islands,SB 225 | 177.7908632460372,-7.077587264899652,Tuvalu,TV,Tuvalu,TV 226 | 168.03401497043464,-16.479658326860534,Vanuatu,VU,Vanuatu,VU 227 | 105.03973078680701,12.699186865507775,Cambodia,KH,Cambodia,KH 228 | 103.76375899026448,18.117282736873282,Laos,LA,Laos,LA 229 | 109.38825444685766,4.304358978251201,Malaysia,MY,Malaysia,MY 230 | 97.08691544807498,19.7773765841526,Myanmar,MM,Myanmar,MM 231 | 103.81025757634053,1.3528251890006349,Singapore,SG,Singapore,SG 232 | 101.06860621475552,13.596475025422246,Thailand,TH,Thailand,TH 233 | 105.79110320454193,16.374291050391896,Vietnam,VN,Vietnam,VN 234 | 90.43212562608613,23.673728665121,Bangladesh,BD,Bangladesh,BD 235 | 90.46716647173861,27.42163933959824,Bhutan,BT,Bhutan,BT 236 | 105.45120548784291,37.458640079762894,China,CN,China,CN 237 | 114.79362404227638,4.524564529891025,Brunei Darussalam,BN,Brunei Darussalam,BN 238 | 121.86964934640937,10.803250497287834,Philippines,PH,Philippines,PH 239 | 127.63138763851518,36.05236463716811,South Korea,KR,South Korea,KR 240 | 103.3987360327455,47.08644454604851,Mongolia,MN,Mongolia,MN 241 | 127.3379805653744,40.19198091470839,North Korea,KP,North Korea,KP 242 | 144.78024458298802,13.445430479945276,Guam,GU,United States,US 243 | 135.44649610719037,35.83580347196827,Japan,JP,Japan,JP 244 | 167.47185427320863,10.051054424749758,Marshall Islands,MH,Marshall Islands,MH 245 | 160.41981307706675,6.1606517443131565,Micronesia,FM,Micronesia,FM 246 | 145.68468719023744,15.090138493332644,Northern Mariana Islands,MP,United States,US 247 | 134.5666403460281,7.507585985168558,Palau,PW,Palau,PW 248 | 98.96988771839898,61.452642935773156,Russian Federation,RU,Russian Federation,RU 249 | -2.9429673360930226,40.03038547506125,Spain,ES,Spain,ES 250 | -15.920136671626393,28.41924762477911,Canarias,ES,Spain,ES -------------------------------------------------------------------------------- /data/geojson/usa-state-capitals.geojson: -------------------------------------------------------------------------------- 1 | { 2 | "type": "FeatureCollection", 3 | "features": [ 4 | { 5 | "type": "Feature", 6 | "properties": { 7 | "State": "Alabama", 8 | "ST": "AL", 9 | "Capital": "Montgomery", 10 | "Longitude": "-86.300280684889", 11 | "Latitude": "32.3778448300578" 12 | }, 13 | "geometry": { 14 | "type": "Point", 15 | "coordinates": [ 16 | -86.300281, 17 | 32.377845 18 | ] 19 | } 20 | }, 21 | { 22 | "type": "Feature", 23 | "properties": { 24 | "State": "Alaska", 25 | "ST": "AK", 26 | "Capital": "Juneau", 27 | "Longitude": "-134.419720089079", 28 | "Latitude": "58.3019435628538" 29 | }, 30 | "geometry": { 31 | "type": "Point", 32 | "coordinates": [ 33 | -134.41972, 34 | 58.301944 35 | ] 36 | } 37 | }, 38 | { 39 | "type": "Feature", 40 | "properties": { 41 | "State": "Arizona", 42 | "ST": "AZ", 43 | "Capital": "Phoenix", 44 | "Longitude": "-112.097002114648", 45 | "Latitude": "33.448056962118" 46 | }, 47 | "geometry": { 48 | "type": "Point", 49 | "coordinates": [ 50 | -112.097002, 51 | 33.448057 52 | ] 53 | } 54 | }, 55 | { 56 | "type": "Feature", 57 | "properties": { 58 | "State": "Arkansas", 59 | "ST": "AR", 60 | "Capital": "Little Rock", 61 | "Longitude": "-92.2891966155731", 62 | "Latitude": "34.74671389912" 63 | }, 64 | "geometry": { 65 | "type": "Point", 66 | "coordinates": [ 67 | -92.289197, 68 | 34.746714 69 | ] 70 | } 71 | }, 72 | { 73 | "type": "Feature", 74 | "properties": { 75 | "State": "California", 76 | "ST": "CA", 77 | "Capital": "Sacramento", 78 | "Longitude": "-121.493173407028", 79 | "Latitude": "38.5766379822497" 80 | }, 81 | "geometry": { 82 | "type": "Point", 83 | "coordinates": [ 84 | -121.493173, 85 | 38.576638 86 | ] 87 | } 88 | }, 89 | { 90 | "type": "Feature", 91 | "properties": { 92 | "State": "Colorado", 93 | "ST": "CO", 94 | "Capital": "Denver", 95 | "Longitude": "-104.984882535635", 96 | "Latitude": "39.7393011782883" 97 | }, 98 | "geometry": { 99 | "type": "Point", 100 | "coordinates": [ 101 | -104.984883, 102 | 39.739301 103 | ] 104 | } 105 | }, 106 | { 107 | "type": "Feature", 108 | "properties": { 109 | "State": "Connecticut", 110 | "ST": "CT", 111 | "Capital": "Hartford", 112 | "Longitude": "-72.682265685282", 113 | "Latitude": "41.7640478075494" 114 | }, 115 | "geometry": { 116 | "type": "Point", 117 | "coordinates": [ 118 | -72.682266, 119 | 41.764048 120 | ] 121 | } 122 | }, 123 | { 124 | "type": "Feature", 125 | "properties": { 126 | "State": "Delaware", 127 | "ST": "DE", 128 | "Capital": "Dover", 129 | "Longitude": "-75.521440669349", 130 | "Latitude": "39.1598182563424" 131 | }, 132 | "geometry": { 133 | "type": "Point", 134 | "coordinates": [ 135 | -75.521441, 136 | 39.159818 137 | ] 138 | } 139 | }, 140 | { 141 | "type": "Feature", 142 | "properties": { 143 | "State": "Florida", 144 | "ST": "FL", 145 | "Capital": "Tallahassee", 146 | "Longitude": "-84.2814103124204", 147 | "Latitude": "30.4379800379088" 148 | }, 149 | "geometry": { 150 | "type": "Point", 151 | "coordinates": [ 152 | -84.28141, 153 | 30.43798 154 | ] 155 | } 156 | }, 157 | { 158 | "type": "Feature", 159 | "properties": { 160 | "State": "Georgia", 161 | "ST": "GA", 162 | "Capital": "Atlanta", 163 | "Longitude": "-84.3882728102467", 164 | "Latitude": "33.7491105069311" 165 | }, 166 | "geometry": { 167 | "type": "Point", 168 | "coordinates": [ 169 | -84.388273, 170 | 33.749111 171 | ] 172 | } 173 | }, 174 | { 175 | "type": "Feature", 176 | "properties": { 177 | "State": "Hawaii", 178 | "ST": "HI", 179 | "Capital": "Honolulu", 180 | "Longitude": "-157.857644685749", 181 | "Latitude": "21.3071891251897" 182 | }, 183 | "geometry": { 184 | "type": "Point", 185 | "coordinates": [ 186 | -157.857645, 187 | 21.307189 188 | ] 189 | } 190 | }, 191 | { 192 | "type": "Feature", 193 | "properties": { 194 | "State": "Idaho", 195 | "ST": "ID", 196 | "Capital": "Boise", 197 | "Longitude": "-116.200071549668", 198 | "Latitude": "43.6173976205726" 199 | }, 200 | "geometry": { 201 | "type": "Point", 202 | "coordinates": [ 203 | -116.200072, 204 | 43.617398 205 | ] 206 | } 207 | }, 208 | { 209 | "type": "Feature", 210 | "properties": { 211 | "State": "Illinois", 212 | "ST": "IL", 213 | "Capital": "Springfield", 214 | "Longitude": "-89.6838561293087", 215 | "Latitude": "39.7992266437577" 216 | }, 217 | "geometry": { 218 | "type": "Point", 219 | "coordinates": [ 220 | -89.683856, 221 | 39.799227 222 | ] 223 | } 224 | }, 225 | { 226 | "type": "Feature", 227 | "properties": { 228 | "State": "Indiana", 229 | "ST": "IN", 230 | "Capital": "Indianapolis", 231 | "Longitude": "-86.1619162318749", 232 | "Latitude": "39.7682876590079" 233 | }, 234 | "geometry": { 235 | "type": "Point", 236 | "coordinates": [ 237 | -86.161916, 238 | 39.768288 239 | ] 240 | } 241 | }, 242 | { 243 | "type": "Feature", 244 | "properties": { 245 | "State": "Iowa", 246 | "ST": "IA", 247 | "Capital": "Des Moines", 248 | "Longitude": "-93.6038299676467", 249 | "Latitude": "41.591203450586" 250 | }, 251 | "geometry": { 252 | "type": "Point", 253 | "coordinates": [ 254 | -93.60383, 255 | 41.591203 256 | ] 257 | } 258 | }, 259 | { 260 | "type": "Feature", 261 | "properties": { 262 | "State": "Kansas", 263 | "ST": "KS", 264 | "Capital": "Topeka", 265 | "Longitude": "-95.6781165783569", 266 | "Latitude": "39.0481868390344" 267 | }, 268 | "geometry": { 269 | "type": "Point", 270 | "coordinates": [ 271 | -95.678117, 272 | 39.048187 273 | ] 274 | } 275 | }, 276 | { 277 | "type": "Feature", 278 | "properties": { 279 | "State": "Kentucky", 280 | "ST": "KY", 281 | "Capital": "Frankfort", 282 | "Longitude": "-84.8752029177421", 283 | "Latitude": "38.1868295579102" 284 | }, 285 | "geometry": { 286 | "type": "Point", 287 | "coordinates": [ 288 | -84.875203, 289 | 38.18683 290 | ] 291 | } 292 | }, 293 | { 294 | "type": "Feature", 295 | "properties": { 296 | "State": "Louisiana", 297 | "ST": "LA", 298 | "Capital": "Baton Rouge", 299 | "Longitude": "-91.1873435440524", 300 | "Latitude": "30.4561959742174" 301 | }, 302 | "geometry": { 303 | "type": "Point", 304 | "coordinates": [ 305 | -91.187344, 306 | 30.456196 307 | ] 308 | } 309 | }, 310 | { 311 | "type": "Feature", 312 | "properties": { 313 | "State": "Maine", 314 | "ST": "ME", 315 | "Capital": "Augusta", 316 | "Longitude": "-69.7824740545278", 317 | "Latitude": "44.3068311917176" 318 | }, 319 | "geometry": { 320 | "type": "Point", 321 | "coordinates": [ 322 | -69.782474, 323 | 44.306831 324 | ] 325 | } 326 | }, 327 | { 328 | "type": "Feature", 329 | "properties": { 330 | "State": "Maryland", 331 | "ST": "MD", 332 | "Capital": "Annapolis", 333 | "Longitude": "-76.490730353326", 334 | "Latitude": "38.9788809750953" 335 | }, 336 | "geometry": { 337 | "type": "Point", 338 | "coordinates": [ 339 | -76.49073, 340 | 38.978881 341 | ] 342 | } 343 | }, 344 | { 345 | "type": "Feature", 346 | "properties": { 347 | "State": "Massachusetts", 348 | "ST": "MA", 349 | "Capital": "Boston", 350 | "Longitude": "-71.0635920009677", 351 | "Latitude": "42.3585156598684" 352 | }, 353 | "geometry": { 354 | "type": "Point", 355 | "coordinates": [ 356 | -71.063592, 357 | 42.358516 358 | ] 359 | } 360 | }, 361 | { 362 | "type": "Feature", 363 | "properties": { 364 | "State": "Michigan", 365 | "ST": "MI", 366 | "Capital": "Lansing", 367 | "Longitude": "-84.5554894724477", 368 | "Latitude": "42.7337559214066" 369 | }, 370 | "geometry": { 371 | "type": "Point", 372 | "coordinates": [ 373 | -84.555489, 374 | 42.733756 375 | ] 376 | } 377 | }, 378 | { 379 | "type": "Feature", 380 | "properties": { 381 | "State": "Minnesota", 382 | "ST": "MN", 383 | "Capital": "St. Paul", 384 | "Longitude": "-93.1023668129999", 385 | "Latitude": "44.9544483754758" 386 | }, 387 | "geometry": { 388 | "type": "Point", 389 | "coordinates": [ 390 | -93.102367, 391 | 44.954448 392 | ] 393 | } 394 | }, 395 | { 396 | "type": "Feature", 397 | "properties": { 398 | "State": "Mississippi", 399 | "ST": "MS", 400 | "Capital": "Jackson", 401 | "Longitude": "-90.1821570985857", 402 | "Latitude": "32.3038596464079" 403 | }, 404 | "geometry": { 405 | "type": "Point", 406 | "coordinates": [ 407 | -90.182157, 408 | 32.30386 409 | ] 410 | } 411 | }, 412 | { 413 | "type": "Feature", 414 | "properties": { 415 | "State": "Missouri", 416 | "ST": "MO", 417 | "Capital": "Jefferson City", 418 | "Longitude": "-92.1729471612446", 419 | "Latitude": "38.5792342520804" 420 | }, 421 | "geometry": { 422 | "type": "Point", 423 | "coordinates": [ 424 | -92.172947, 425 | 38.579234 426 | ] 427 | } 428 | }, 429 | { 430 | "type": "Feature", 431 | "properties": { 432 | "State": "Montana", 433 | "ST": "MT", 434 | "Capital": "Helena", 435 | "Longitude": "-112.017030200267", 436 | "Latitude": "46.5844748792441" 437 | }, 438 | "geometry": { 439 | "type": "Point", 440 | "coordinates": [ 441 | -112.01703, 442 | 46.584475 443 | ] 444 | } 445 | }, 446 | { 447 | "type": "Feature", 448 | "properties": { 449 | "State": "Nebraska", 450 | "ST": "NE", 451 | "Capital": "Lincoln", 452 | "Longitude": "-96.6997323196763", 453 | "Latitude": "40.8080846893224" 454 | }, 455 | "geometry": { 456 | "type": "Point", 457 | "coordinates": [ 458 | -96.699732, 459 | 40.808085 460 | ] 461 | } 462 | }, 463 | { 464 | "type": "Feature", 465 | "properties": { 466 | "State": "Nevada", 467 | "ST": "NV", 468 | "Capital": "Carson City", 469 | "Longitude": "-119.765996538968", 470 | "Latitude": "39.1639658818133" 471 | }, 472 | "geometry": { 473 | "type": "Point", 474 | "coordinates": [ 475 | -119.765997, 476 | 39.163966 477 | ] 478 | } 479 | }, 480 | { 481 | "type": "Feature", 482 | "properties": { 483 | "State": "New Hampshire", 484 | "ST": "NH", 485 | "Capital": "Concord", 486 | "Longitude": "-71.5360412913525", 487 | "Latitude": "43.2077286653951" 488 | }, 489 | "geometry": { 490 | "type": "Point", 491 | "coordinates": [ 492 | -71.536041, 493 | 43.207729 494 | ] 495 | } 496 | }, 497 | { 498 | "type": "Feature", 499 | "properties": { 500 | "State": "New Jersey", 501 | "ST": "NJ", 502 | "Capital": "Trenton", 503 | "Longitude": "-74.7701082395055", 504 | "Latitude": "40.2205925416604" 505 | }, 506 | "geometry": { 507 | "type": "Point", 508 | "coordinates": [ 509 | -74.770108, 510 | 40.220593 511 | ] 512 | } 513 | }, 514 | { 515 | "type": "Feature", 516 | "properties": { 517 | "State": "New Mexico", 518 | "ST": "NM", 519 | "Capital": "Santa Fe", 520 | "Longitude": "-105.939263846866", 521 | "Latitude": "35.682385674315" 522 | }, 523 | "geometry": { 524 | "type": "Point", 525 | "coordinates": [ 526 | -105.939264, 527 | 35.682386 528 | ] 529 | } 530 | }, 531 | { 532 | "type": "Feature", 533 | "properties": { 534 | "State": "New York", 535 | "ST": "NY", 536 | "Capital": "Albany", 537 | "Longitude": "-73.7584566763079", 538 | "Latitude": "42.6531923942429" 539 | }, 540 | "geometry": { 541 | "type": "Point", 542 | "coordinates": [ 543 | -73.758457, 544 | 42.653192 545 | ] 546 | } 547 | }, 548 | { 549 | "type": "Feature", 550 | "properties": { 551 | "State": "North Carolina", 552 | "ST": "NC", 553 | "Capital": "Raleigh", 554 | "Longitude": "-78.6390536727153", 555 | "Latitude": "35.7808620976202" 556 | }, 557 | "geometry": { 558 | "type": "Point", 559 | "coordinates": [ 560 | -78.639054, 561 | 35.780862 562 | ] 563 | } 564 | }, 565 | { 566 | "type": "Feature", 567 | "properties": { 568 | "State": "North Dakota", 569 | "ST": "ND", 570 | "Capital": "Bismarck", 571 | "Longitude": "-100.782425301832", 572 | "Latitude": "46.8204800624107" 573 | }, 574 | "geometry": { 575 | "type": "Point", 576 | "coordinates": [ 577 | -100.782425, 578 | 46.82048 579 | ] 580 | } 581 | }, 582 | { 583 | "type": "Feature", 584 | "properties": { 585 | "State": "Ohio", 586 | "ST": "OH", 587 | "Capital": "Columbus", 588 | "Longitude": "-83.000216483074", 589 | "Latitude": "39.9611972655304" 590 | }, 591 | "geometry": { 592 | "type": "Point", 593 | "coordinates": [ 594 | -83.000216, 595 | 39.961197 596 | ] 597 | } 598 | }, 599 | { 600 | "type": "Feature", 601 | "properties": { 602 | "State": "Oklahoma", 603 | "ST": "OK", 604 | "Capital": "Oklahoma City", 605 | "Longitude": "-97.5033086417702", 606 | "Latitude": "35.4930913156566" 607 | }, 608 | "geometry": { 609 | "type": "Point", 610 | "coordinates": [ 611 | -97.503309, 612 | 35.493091 613 | ] 614 | } 615 | }, 616 | { 617 | "type": "Feature", 618 | "properties": { 619 | "State": "Oregon", 620 | "ST": "OR", 621 | "Capital": "Salem", 622 | "Longitude": "-123.030608818409", 623 | "Latitude": "44.9383658965847" 624 | }, 625 | "geometry": { 626 | "type": "Point", 627 | "coordinates": [ 628 | -123.030609, 629 | 44.938366 630 | ] 631 | } 632 | }, 633 | { 634 | "type": "Feature", 635 | "properties": { 636 | "State": "Pennsylvania", 637 | "ST": "PA", 638 | "Capital": "Harrisburg", 639 | "Longitude": "-76.8841110484574", 640 | "Latitude": "40.2651554758888" 641 | }, 642 | "geometry": { 643 | "type": "Point", 644 | "coordinates": [ 645 | -76.884111, 646 | 40.265155 647 | ] 648 | } 649 | }, 650 | { 651 | "type": "Feature", 652 | "properties": { 653 | "State": "Rhode Island", 654 | "ST": "RI", 655 | "Capital": "Providence", 656 | "Longitude": "-71.4150694021695", 657 | "Latitude": "41.8304368543275" 658 | }, 659 | "geometry": { 660 | "type": "Point", 661 | "coordinates": [ 662 | -71.415069, 663 | 41.830437 664 | ] 665 | } 666 | }, 667 | { 668 | "type": "Feature", 669 | "properties": { 670 | "State": "South Carolina", 671 | "ST": "SC", 672 | "Capital": "Columbia", 673 | "Longitude": "-81.033361075349", 674 | "Latitude": "34.0006222412432" 675 | }, 676 | "geometry": { 677 | "type": "Point", 678 | "coordinates": [ 679 | -81.033361, 680 | 34.000622 681 | ] 682 | } 683 | }, 684 | { 685 | "type": "Feature", 686 | "properties": { 687 | "State": "South Dakota", 688 | "ST": "SD", 689 | "Capital": "Pierre", 690 | "Longitude": "-100.345546329203", 691 | "Latitude": "44.3671499721808" 692 | }, 693 | "geometry": { 694 | "type": "Point", 695 | "coordinates": [ 696 | -100.345546, 697 | 44.36715 698 | ] 699 | } 700 | }, 701 | { 702 | "type": "Feature", 703 | "properties": { 704 | "State": "Tennessee", 705 | "ST": "TN", 706 | "Capital": "Nashville", 707 | "Longitude": "-86.7844011981955", 708 | "Latitude": "36.1658136639888" 709 | }, 710 | "geometry": { 711 | "type": "Point", 712 | "coordinates": [ 713 | -86.784401, 714 | 36.165814 715 | ] 716 | } 717 | }, 718 | { 719 | "type": "Feature", 720 | "properties": { 721 | "State": "Texas", 722 | "ST": "TX", 723 | "Capital": "Austin", 724 | "Longitude": "-97.7403787162921", 725 | "Latitude": "30.2746490151032" 726 | }, 727 | "geometry": { 728 | "type": "Point", 729 | "coordinates": [ 730 | -97.740379, 731 | 30.274649 732 | ] 733 | } 734 | }, 735 | { 736 | "type": "Feature", 737 | "properties": { 738 | "State": "Utah", 739 | "ST": "UT", 740 | "Capital": "Salt Lake City", 741 | "Longitude": "-111.888143519988", 742 | "Latitude": "40.7765189566751" 743 | }, 744 | "geometry": { 745 | "type": "Point", 746 | "coordinates": [ 747 | -111.888144, 748 | 40.776519 749 | ] 750 | } 751 | }, 752 | { 753 | "type": "Feature", 754 | "properties": { 755 | "State": "Vermont", 756 | "ST": "VT", 757 | "Capital": "Montpelier", 758 | "Longitude": "-72.5804431413164", 759 | "Latitude": "44.2619812631813" 760 | }, 761 | "geometry": { 762 | "type": "Point", 763 | "coordinates": [ 764 | -72.580443, 765 | 44.261981 766 | ] 767 | } 768 | }, 769 | { 770 | "type": "Feature", 771 | "properties": { 772 | "State": "Virginia", 773 | "ST": "VA", 774 | "Capital": "Richmond", 775 | "Longitude": "-77.4334960632491", 776 | "Latitude": "37.5387725441582" 777 | }, 778 | "geometry": { 779 | "type": "Point", 780 | "coordinates": [ 781 | -77.433496, 782 | 37.538773 783 | ] 784 | } 785 | }, 786 | { 787 | "type": "Feature", 788 | "properties": { 789 | "State": "Washington", 790 | "ST": "WA", 791 | "Capital": "Olympia", 792 | "Longitude": "-122.904762637417", 793 | "Latitude": "47.0362418589047" 794 | }, 795 | "geometry": { 796 | "type": "Point", 797 | "coordinates": [ 798 | -122.904763, 799 | 47.036242 800 | ] 801 | } 802 | }, 803 | { 804 | "type": "Feature", 805 | "properties": { 806 | "State": "West Virginia", 807 | "ST": "WV", 808 | "Capital": "Charleston", 809 | "Longitude": "-81.6126542355569", 810 | "Latitude": "38.3363786775331" 811 | }, 812 | "geometry": { 813 | "type": "Point", 814 | "coordinates": [ 815 | -81.612654, 816 | 38.336379 817 | ] 818 | } 819 | }, 820 | { 821 | "type": "Feature", 822 | "properties": { 823 | "State": "Wisconsin", 824 | "ST": "WI", 825 | "Capital": "Madison", 826 | "Longitude": "-89.384196048713", 827 | "Latitude": "43.0752429469311" 828 | }, 829 | "geometry": { 830 | "type": "Point", 831 | "coordinates": [ 832 | -89.384196, 833 | 43.075243 834 | ] 835 | } 836 | }, 837 | { 838 | "type": "Feature", 839 | "properties": { 840 | "State": "Wyoming", 841 | "ST": "WY", 842 | "Capital": "Cheyenne", 843 | "Longitude": "-104.820410067003", 844 | "Latitude": "41.1407764260928" 845 | }, 846 | "geometry": { 847 | "type": "Point", 848 | "coordinates": [ 849 | -104.82041, 850 | 41.140776 851 | ] 852 | } 853 | } 854 | ] 855 | } 856 | -------------------------------------------------------------------------------- /data/json/usa-state-capitals.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "State": "Alabama", 4 | "ST": "AL", 5 | "Capital": "Montgomery", 6 | "Longitude": -86.300280684889, 7 | "Latitude": 32.3778448300578 8 | }, 9 | { 10 | "State": "Alaska", 11 | "ST": "AK", 12 | "Capital": "Juneau", 13 | "Longitude": -134.419720089079, 14 | "Latitude": 58.3019435628538 15 | }, 16 | { 17 | "State": "Arizona", 18 | "ST": "AZ", 19 | "Capital": "Phoenix", 20 | "Longitude": -112.097002114648, 21 | "Latitude": 33.448056962118 22 | }, 23 | { 24 | "State": "Arkansas", 25 | "ST": "AR", 26 | "Capital": "Little Rock", 27 | "Longitude": -92.2891966155731, 28 | "Latitude": 34.74671389912 29 | }, 30 | { 31 | "State": "California", 32 | "ST": "CA", 33 | "Capital": "Sacramento", 34 | "Longitude": -121.493173407028, 35 | "Latitude": 38.5766379822497 36 | }, 37 | { 38 | "State": "Colorado", 39 | "ST": "CO", 40 | "Capital": "Denver", 41 | "Longitude": -104.984882535635, 42 | "Latitude": 39.7393011782883 43 | }, 44 | { 45 | "State": "Connecticut", 46 | "ST": "CT", 47 | "Capital": "Hartford", 48 | "Longitude": -72.682265685282, 49 | "Latitude": 41.7640478075494 50 | }, 51 | { 52 | "State": "Delaware", 53 | "ST": "DE", 54 | "Capital": "Dover", 55 | "Longitude": -75.521440669349, 56 | "Latitude": 39.1598182563424 57 | }, 58 | { 59 | "State": "Florida", 60 | "ST": "FL", 61 | "Capital": "Tallahassee", 62 | "Longitude": -84.2814103124204, 63 | "Latitude": 30.4379800379088 64 | }, 65 | { 66 | "State": "Georgia", 67 | "ST": "GA", 68 | "Capital": "Atlanta", 69 | "Longitude": -84.3882728102467, 70 | "Latitude": 33.7491105069311 71 | }, 72 | { 73 | "State": "Hawaii", 74 | "ST": "HI", 75 | "Capital": "Honolulu", 76 | "Longitude": -157.857644685749, 77 | "Latitude": 21.3071891251897 78 | }, 79 | { 80 | "State": "Idaho", 81 | "ST": "ID", 82 | "Capital": "Boise", 83 | "Longitude": -116.200071549668, 84 | "Latitude": 43.6173976205726 85 | }, 86 | { 87 | "State": "Illinois", 88 | "ST": "IL", 89 | "Capital": "Springfield", 90 | "Longitude": -89.6838561293087, 91 | "Latitude": 39.7992266437577 92 | }, 93 | { 94 | "State": "Indiana", 95 | "ST": "IN", 96 | "Capital": "Indianapolis", 97 | "Longitude": -86.1619162318749, 98 | "Latitude": 39.7682876590079 99 | }, 100 | { 101 | "State": "Iowa", 102 | "ST": "IA", 103 | "Capital": "Des Moines", 104 | "Longitude": -93.6038299676467, 105 | "Latitude": 41.591203450586 106 | }, 107 | { 108 | "State": "Kansas", 109 | "ST": "KS", 110 | "Capital": "Topeka", 111 | "Longitude": -95.6781165783569, 112 | "Latitude": 39.0481868390344 113 | }, 114 | { 115 | "State": "Kentucky", 116 | "ST": "KY", 117 | "Capital": "Frankfort", 118 | "Longitude": -84.8752029177421, 119 | "Latitude": 38.1868295579102 120 | }, 121 | { 122 | "State": "Louisiana", 123 | "ST": "LA", 124 | "Capital": "Baton Rouge", 125 | "Longitude": -91.1873435440524, 126 | "Latitude": 30.4561959742174 127 | }, 128 | { 129 | "State": "Maine", 130 | "ST": "ME", 131 | "Capital": "Augusta", 132 | "Longitude": -69.7824740545278, 133 | "Latitude": 44.3068311917176 134 | }, 135 | { 136 | "State": "Maryland", 137 | "ST": "MD", 138 | "Capital": "Annapolis", 139 | "Longitude": -76.490730353326, 140 | "Latitude": 38.9788809750953 141 | }, 142 | { 143 | "State": "Massachusetts", 144 | "ST": "MA", 145 | "Capital": "Boston", 146 | "Longitude": -71.0635920009677, 147 | "Latitude": 42.3585156598684 148 | }, 149 | { 150 | "State": "Michigan", 151 | "ST": "MI", 152 | "Capital": "Lansing", 153 | "Longitude": -84.5554894724477, 154 | "Latitude": 42.7337559214066 155 | }, 156 | { 157 | "State": "Minnesota", 158 | "ST": "MN", 159 | "Capital": "St. Paul", 160 | "Longitude": -93.1023668129999, 161 | "Latitude": 44.9544483754758 162 | }, 163 | { 164 | "State": "Mississippi", 165 | "ST": "MS", 166 | "Capital": "Jackson", 167 | "Longitude": -90.1821570985857, 168 | "Latitude": 32.3038596464079 169 | }, 170 | { 171 | "State": "Missouri", 172 | "ST": "MO", 173 | "Capital": "Jefferson City", 174 | "Longitude": -92.1729471612446, 175 | "Latitude": 38.5792342520804 176 | }, 177 | { 178 | "State": "Montana", 179 | "ST": "MT", 180 | "Capital": "Helena", 181 | "Longitude": -112.017030200267, 182 | "Latitude": 46.5844748792441 183 | }, 184 | { 185 | "State": "Nebraska", 186 | "ST": "NE", 187 | "Capital": "Lincoln", 188 | "Longitude": -96.6997323196763, 189 | "Latitude": 40.8080846893224 190 | }, 191 | { 192 | "State": "Nevada", 193 | "ST": "NV", 194 | "Capital": "Carson City", 195 | "Longitude": -119.765996538968, 196 | "Latitude": 39.1639658818133 197 | }, 198 | { 199 | "State": "New Hampshire", 200 | "ST": "NH", 201 | "Capital": "Concord", 202 | "Longitude": -71.5360412913525, 203 | "Latitude": 43.2077286653951 204 | }, 205 | { 206 | "State": "New Jersey", 207 | "ST": "NJ", 208 | "Capital": "Trenton", 209 | "Longitude": -74.7701082395055, 210 | "Latitude": 40.2205925416604 211 | }, 212 | { 213 | "State": "New Mexico", 214 | "ST": "NM", 215 | "Capital": "Santa Fe", 216 | "Longitude": -105.939263846866, 217 | "Latitude": 35.682385674315 218 | }, 219 | { 220 | "State": "New York", 221 | "ST": "NY", 222 | "Capital": "Albany", 223 | "Longitude": -73.7584566763079, 224 | "Latitude": 42.6531923942429 225 | }, 226 | { 227 | "State": "North Carolina", 228 | "ST": "NC", 229 | "Capital": "Raleigh", 230 | "Longitude": -78.6390536727153, 231 | "Latitude": 35.7808620976202 232 | }, 233 | { 234 | "State": "North Dakota", 235 | "ST": "ND", 236 | "Capital": "Bismarck", 237 | "Longitude": -100.782425301832, 238 | "Latitude": 46.8204800624107 239 | }, 240 | { 241 | "State": "Ohio", 242 | "ST": "OH", 243 | "Capital": "Columbus", 244 | "Longitude": -83.000216483074, 245 | "Latitude": 39.9611972655304 246 | }, 247 | { 248 | "State": "Oklahoma", 249 | "ST": "OK", 250 | "Capital": "Oklahoma City", 251 | "Longitude": -97.5033086417702, 252 | "Latitude": 35.4930913156566 253 | }, 254 | { 255 | "State": "Oregon", 256 | "ST": "OR", 257 | "Capital": "Salem", 258 | "Longitude": -123.030608818409, 259 | "Latitude": 44.9383658965847 260 | }, 261 | { 262 | "State": "Pennsylvania", 263 | "ST": "PA", 264 | "Capital": "Harrisburg", 265 | "Longitude": -76.8841110484574, 266 | "Latitude": 40.2651554758888 267 | }, 268 | { 269 | "State": "Rhode Island", 270 | "ST": "RI", 271 | "Capital": "Providence", 272 | "Longitude": -71.4150694021695, 273 | "Latitude": 41.8304368543275 274 | }, 275 | { 276 | "State": "South Carolina", 277 | "ST": "SC", 278 | "Capital": "Columbia", 279 | "Longitude": -81.033361075349, 280 | "Latitude": 34.0006222412432 281 | }, 282 | { 283 | "State": "South Dakota", 284 | "ST": "SD", 285 | "Capital": "Pierre", 286 | "Longitude": -100.345546329203, 287 | "Latitude": 44.3671499721808 288 | }, 289 | { 290 | "State": "Tennessee", 291 | "ST": "TN", 292 | "Capital": "Nashville", 293 | "Longitude": -86.7844011981955, 294 | "Latitude": 36.1658136639888 295 | }, 296 | { 297 | "State": "Texas", 298 | "ST": "TX", 299 | "Capital": "Austin", 300 | "Longitude": -97.7403787162921, 301 | "Latitude": 30.2746490151032 302 | }, 303 | { 304 | "State": "Utah", 305 | "ST": "UT", 306 | "Capital": "Salt Lake City", 307 | "Longitude": -111.888143519988, 308 | "Latitude": 40.7765189566751 309 | }, 310 | { 311 | "State": "Vermont", 312 | "ST": "VT", 313 | "Capital": "Montpelier", 314 | "Longitude": -72.5804431413164, 315 | "Latitude": 44.2619812631813 316 | }, 317 | { 318 | "State": "Virginia", 319 | "ST": "VA", 320 | "Capital": "Richmond", 321 | "Longitude": -77.4334960632491, 322 | "Latitude": 37.5387725441582 323 | }, 324 | { 325 | "State": "Washington", 326 | "ST": "WA", 327 | "Capital": "Olympia", 328 | "Longitude": -122.904762637417, 329 | "Latitude": 47.0362418589047 330 | }, 331 | { 332 | "State": "West Virginia", 333 | "ST": "WV", 334 | "Capital": "Charleston", 335 | "Longitude": -81.6126542355569, 336 | "Latitude": 38.3363786775331 337 | }, 338 | { 339 | "State": "Wisconsin", 340 | "ST": "WI", 341 | "Capital": "Madison", 342 | "Longitude": -89.384196048713, 343 | "Latitude": 43.0752429469311 344 | }, 345 | { 346 | "State": "Wyoming", 347 | "ST": "WY", 348 | "Capital": "Cheyenne", 349 | "Longitude": -104.820410067003, 350 | "Latitude": 41.1407764260928 351 | } 352 | ] -------------------------------------------------------------------------------- /docs/images/data-table-notebook-examples.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RandomFractals/unfolded-map-renderer/f4b457d19ad1e2e017adece1649f5eb274a17326/docs/images/data-table-notebook-examples.png -------------------------------------------------------------------------------- /docs/images/equals.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RandomFractals/unfolded-map-renderer/f4b457d19ad1e2e017adece1649f5eb274a17326/docs/images/equals.png -------------------------------------------------------------------------------- /docs/images/heart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RandomFractals/unfolded-map-renderer/f4b457d19ad1e2e017adece1649f5eb274a17326/docs/images/heart.png -------------------------------------------------------------------------------- /docs/images/notebook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RandomFractals/unfolded-map-renderer/f4b457d19ad1e2e017adece1649f5eb274a17326/docs/images/notebook.png -------------------------------------------------------------------------------- /docs/images/plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RandomFractals/unfolded-map-renderer/f4b457d19ad1e2e017adece1649f5eb274a17326/docs/images/plus.png -------------------------------------------------------------------------------- /docs/images/unfolded-map-geojson.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RandomFractals/unfolded-map-renderer/f4b457d19ad1e2e017adece1649f5eb274a17326/docs/images/unfolded-map-geojson.png -------------------------------------------------------------------------------- /docs/images/unfolded-map-notebook-renderer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RandomFractals/unfolded-map-renderer/f4b457d19ad1e2e017adece1649f5eb274a17326/docs/images/unfolded-map-notebook-renderer.png -------------------------------------------------------------------------------- /docs/images/unfolded-map-text-output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RandomFractals/unfolded-map-renderer/f4b457d19ad1e2e017adece1649f5eb274a17326/docs/images/unfolded-map-text-output.png -------------------------------------------------------------------------------- /docs/images/unfolded.jfif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RandomFractals/unfolded-map-renderer/f4b457d19ad1e2e017adece1649f5eb274a17326/docs/images/unfolded.jfif -------------------------------------------------------------------------------- /notebooks/chicago-red-light-cameras-pyolite.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "source": [ 6 | "# Chicago Red Light Cameras Pyolite Notebook 📓\r\n", 7 | "\r\n", 8 | "Data Source: [Chicago Transportation](https://data.cityofchicago.org/browse?category=Transportation)/[Red Light Camera Locations](https://data.cityofchicago.org/Transportation/Red-Light-Camera-Locations/thvf-6diy)" 9 | ], 10 | "metadata": {} 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": null, 15 | "source": [ 16 | "from js import fetch\r\n", 17 | "response = await fetch('https://raw.githubusercontent.com/RandomFractals/vscode-leaflet/main/data/geojson/chicago-red-light-cameras.geojson')\r\n", 18 | "geoJson = await response.text()\r\n", 19 | "geoJson" 20 | ], 21 | "outputs": [], 22 | "metadata": {} 23 | } 24 | ], 25 | "metadata": { 26 | "orig_nbformat": 4, 27 | "language_info": { 28 | "name": "python" 29 | } 30 | }, 31 | "nbformat": 4, 32 | "nbformat_minor": 2 33 | } -------------------------------------------------------------------------------- /notebooks/chicago-red-light-cameras.restbook: -------------------------------------------------------------------------------- 1 | [{"kind":1,"language":"markdown","value":"# Chicago Red Light Cameras REST Book 📓\r\n\r\nData Source: [Chicago Transportation](https://data.cityofchicago.org/browse?category=Transportation)/[Red Light Camera Locations](https://data.cityofchicago.org/Transportation/Red-Light-Camera-Locations/thvf-6diy)\r\n\r\nSee [Chicago Red Light Camera Violations](https://observablehq.com/@randomfractals/chicago-red-light-camera-violations) Observable Notebook 📓 with Top 10 (Busy) Chicago red light cameras graph and daily violations calendar view.","outputs":[]},{"kind":2,"language":"rest-book","value":"GET https://raw.githubusercontent.com/RandomFractals/vscode-leaflet/main/data/csv/chicago-red-light-cameras.csv","outputs":[{"mime":"x-application/rest-book","value":{"status":200,"statusText":"OK","headers":{"Date":"Sat, 06 Nov 2021 18:03:15 GMT","Expires":"Sat, 06 Nov 2021 18:08:15 GMT","Cache-Control":"max-age=300","Content-Type":"text/plain; charset=utf-8","Content-Length":"12201","X-XSS-Protection":"1; mode=block","X-Frame-Options":"deny","Connection":"close"},"config":{"timeout":10000,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","headers":{"Accept":"application/json, text/plain, */*","User-Agent":"axios/0.21.1"}},"request":{"method":"GET","httpVersion":"1.1","responseUrl":"https://raw.githubusercontent.com/RandomFractals/vscode-leaflet/main/data/csv/chicago-red-light-cameras.csv","timeout":10000,"headers":{}},"data":"Intersection,First Approach,Second Aproach,Third Approach,Go Live Date,Latitude,Longitude,Location\nMilwaukee-Devon,SB,WB,,02/28/2009,41.997407,-87.787921,\"(41.997407, -87.787921)\"\nCalifornia-Peterson,NB,EB,,06/29/2009,41.990442,-87.699401,\"(41.990442, -87.699401)\"\nCentral-Addison,SB,EB,,11/15/2010,41.945877,-87.766754,\"(41.945877, -87.766754)\"\nWestern-63rd,NB,EB,,11/12/2007,41.779214,-87.683638,\"(41.779214, -87.683638)\"\nHalsted-79th,NB,EB,,04/30/2008,41.750643,-87.644043,\"(41.750643, -87.644043)\"\nWacker-Lake,NB,SB,,02/19/2018,41.8857,-87.637,\"(41.8857, -87.637)\"\nLaramie-Fullerton,WB,NB,,06/28/2008,41.924106,-87.756147,\"(41.924106, -87.756147)\"\nLafayette-87th,SB,EB,,08/31/2009,41.736271,-87.625445,\"(41.736271, -87.625445)\"\nCanal-Roosevelt,NB,WB,,11/30/2008,41.867252,-87.639216,\"(41.867252, -87.639216)\"\nPulaski-Fullerton,WB,NB,,05/19/2007,41.924484,-87.726769,\"(41.924484, -87.726769)\"\nStony Island-Cornell-67th,NB,NB,,11/26/2007,41.77334,-87.586295,\"(41.77334, -87.586295)\"\nWestern-North,NB,EB,,11/26/2007,41.91032,-87.687222,\"(41.91032, -87.687222)\"\nCottage Grove-71st-South Chicago,NB,SB,,04/30/2008,41.765868,-87.605586,\"(41.765868, -87.605586)\"\nWentworth-Garfield,NB,WB,,05/08/2008,41.794201,-87.630518,\"(41.794201, -87.630518)\"\nState-63rd,SB,WB,,01/18/2006,41.780058,-87.625374,\"(41.780058, -87.625374)\"\nAshland-Division,NB,EB,,10/25/2007,41.903347,-87.667496,\"(41.903347, -87.667496)\"\nCicero-Fullerton,SB,WB,,02/25/2006,41.924237,-87.746302,\"(41.924237, -87.746302)\"\nCicero-Washington,NB,SB,,06/14/2008,41.881815,-87.745339,\"(41.881815, -87.745339)\"\nSacramento-Chicago,NB,WB,,09/18/2009,41.895591,-87.702455,\"(41.895591, -87.702455)\"\nCentral-Fullerton,SB,WB,,10/05/2007,41.92398,-87.765989,\"(41.92398, -87.765989)\"\nWestern-Lawrence,SB,EB,,07/31/2008,41.968614,-87.688906,\"(41.968614, -87.688906)\"\nPulaski-Irving Park,SB,WB,,05/19/2009,41.953646,-87.727617,\"(41.953646, -87.727617)\"\nKedzie-Armitage,SB,WB,,01/23/2009,41.917402,-87.706965,\"(41.917402, -87.706965)\"\nCicero-Diversey,NB,WB,,02/11/2010,41.931533,-87.746595,\"(41.931533, -87.746595)\"\nMilwaukee-Montrose,SB,WB,,03/11/2010,41.960632,-87.754476,\"(41.960632, -87.754476)\"\nWestern-Diversey-Elston,NB,WB,,07/18/2008,41.932179,-87.687883,\"(41.932179, -87.687883)\"\nWestern-Fullerton,NB,SB,,06/29/2009,41.9249,-87.687641,\"(41.9249, -87.687641)\"\nMilwaukee-Diversey,NB,EB,,06/29/2009,41.931984,-87.712251,\"(41.931984, -87.712251)\"\nKedzie-26th,NB,SB,,11/02/2010,41.844518,-87.705042,\"(41.844518, -87.705042)\"\nAshland-87th,SB,WB,,03/31/2007,41.735788,-87.663063,\"(41.735788, -87.663063)\"\nPulaski-Diversey,SB,NB,,05/15/2009,41.931791,-87.726979,\"(41.931791, -87.726979)\"\nKedzie-63rd,NB,WB,,11/26/2007,41.778972,-87.703138,\"(41.778972, -87.703138)\"\nMichigan-Ontario,SB,WB,,01/22/2018,41.893268,-87.624038,\"(41.893268, -87.624038)\"\nWestern-Cermak,SB,EB,,12/29/2009,41.852031,-87.685639,\"(41.852031, -87.685639)\"\nSheridan-Foster,SB,WB,,01/26/2008,41.976396,-87.654993,\"(41.976396, -87.654993)\"\nPulaski-Belmont,SB,EB,,05/19/2007,41.939094,-87.727185,\"(41.939094, -87.727185)\"\nPulaski-North,NB,WB,,11/30/2008,41.909886,-87.72633,\"(41.909886, -87.72633)\"\nStony Island-79th-South Chicago,SB,WB,NB,05/07/2007,41.751506,-87.585823,\"(41.751506, -87.585823)\"\nDamen-63rd,NB,SB,,05/31/2008,41.779315,-87.673906,\"(41.779315, -87.673906)\"\nCicero-North,EB,WB,,05/31/2008,41.909626,-87.746112,\"(41.909626, -87.746112)\"\nBroadway-Sheridan-Devon,SB,EB,,10/18/2007,41.99819,-87.660545,\"(41.99819, -87.660545)\"\nKedzie-47th,NB,WB,,03/30/2008,41.808115,-87.703974,\"(41.808115, -87.703974)\"\nPulaski-Archer-50th,EB,WB,,10/31/2007,41.802317,-87.723422,\"(41.802317, -87.723422)\"\nElston-Lawrence,SB,WB,,06/08/2009,41.968108,-87.740163,\"(41.968108, -87.740163)\"\nDamen-Division,EB,WB,,12/29/2009,41.903191,-87.677258,\"(41.903191, -87.677258)\"\nClark-Irving Park,EB,NB,,07/22/2008,41.954378,-87.662248,\"(41.954378, -87.662248)\"\nAshland-71st,NB,WB,,10/11/2004,41.76491,-87.663794,\"(41.76491, -87.663794)\"\nHamlin-Lake,NB,SB,,05/31/2008,41.885203,-87.720919,\"(41.885203, -87.720919)\"\nAustin-Irving Park,NB,EB,,06/30/2008,41.953055,-87.776775,\"(41.953055, -87.776775)\"\nPulaski-63rd,SB,EB,,03/31/2007,41.778658,-87.722759,\"(41.778658, -87.722759)\"\nLaramie-Madison,EB,WB,,05/11/2011,41.880371,-87.755065,\"(41.880371, -87.755065)\"\nOsceola-Touhy,EB,WB,,10/21/2008,42.011553,-87.812251,\"(42.011553, -87.812251)\"\nPulaski-Armitage,WB,EB,,05/31/2008,41.917165,-87.726559,\"(41.917165, -87.726559)\"\nCalifornia-Devon,NB,EB,,07/31/2008,41.997559,-87.699643,\"(41.997559, -87.699643)\"\nPulaski-Chicago,SB,EB,,02/20/2010,41.895367,-87.726078,\"(41.895367, -87.726078)\"\nDamen-Elston,SB,,,02/17/2006,41.925816,-87.677898,\"(41.925816, -87.677898)\"\nWestern-Madison,NB,WB,,06/01/2004,41.881161,-87.686432,\"(41.881161, -87.686432)\"\nDr Martin Luther King-31st,NB,EB,,06/22/2008,41.838419,-87.617465,\"(41.838419, -87.617465)\"\nPulaski-Roosevelt,NB,WB,,07/17/2009,41.866172,-87.725169,\"(41.866172, -87.725169)\"\nAshland-95th,SB,EB,,06/26/2009,41.721214,-87.662684,\"(41.721214, -87.662684)\"\nHalsted-95th,NB,SB,,04/30/2008,41.721458,-87.643212,\"(41.721458, -87.643212)\"\nDamen-Diversey-Clybourn,SB,WB,,06/30/2008,41.932285,-87.678136,\"(41.932285, -87.678136)\"\nPulaski-Division,NB,SB,,07/22/2009,41.902671,-87.726303,\"(41.902671, -87.726303)\"\nKostner-Grand-North,EB,NB,SB,03/11/2004,41.909754,-87.736262,\"(41.909754, -87.736262)\"\nWestern-Addison,NB,EB,,06/08/2009,41.946731,-87.688258,\"(41.946731, -87.688258)\"\nCicero-47th,SB,WB,,03/31/2008,41.807623,-87.743153,\"(41.807623, -87.743153)\"\nHamlin-Madison,NB,EB,,04/29/2009,41.880789,-87.720752,\"(41.880789, -87.720752)\"\nMichigan-Jackson,NB,EB,,01/22/2018,41.878246,-87.624087,\"(41.878246, -87.624087)\"\nSheridan-Hollywood,WB,EB,,10/18/2007,41.985549,-87.655242,\"(41.985549, -87.655242)\"\nNorthwest Hwy-Foster,SEB,EB,,09/29/2017,41.975688,-87.769261,\"(41.975688, -87.769261)\"\nHalsted-99th,NB,EB,,01/01/2006,41.714215,-87.643004,\"(41.714215, -87.643004)\"\nCicero-Armitage,EB,NB,,11/14/2008,41.916931,-87.746111,\"(41.916931, -87.746111)\"\nAshland-Lawrence,SB,EB,,08/27/2008,41.968876,-87.66944,\"(41.968876, -87.66944)\"\nLaSalle-Kinzie,NB,EB,,04/30/2004,41.889187,-87.632526,\"(41.889187, -87.632526)\"\nWestern-Chicago,NB,EB,,05/07/2007,41.895743,-87.686843,\"(41.895743, -87.686843)\"\nAustin-Addison,EB,NB,,06/28/2008,41.945771,-87.776504,\"(41.945771, -87.776504)\"\nHalsted-Division,NB,WB,,04/07/2004,41.903636,-87.648094,\"(41.903636, -87.648094)\"\nHalsted-111th,SB,WB,,01/01/2006,41.692355,-87.642377,\"(41.692355, -87.642377)\"\nLake Shore-Belmont,SB,EB,,06/22/2008,41.94024,-87.638696,\"(41.94024, -87.638696)\"\nWestern-79th,NB,WB,,05/07/2007,41.750101,-87.682847,\"(41.750101, -87.682847)\"\nWestern-47th,SB,NB,,11/29/2004,41.808426,-87.684425,\"(41.808426, -87.684425)\"\nPulaski-Lawrence,SB,EB,,07/31/2008,41.968242,-87.728027,\"(41.968242, -87.728027)\"\nWestern-55th,SB,EB,,11/01/2003,41.793877,-87.68404,\"(41.793877, -87.68404)\"\nKedzie-71st,SB,WB,,09/17/2009,41.76439,-87.702811,\"(41.76439, -87.702811)\"\nCicero-Peterson,SB,WB,,08/26/2008,41.989898,-87.748325,\"(41.989898, -87.748325)\"\nCalifornia-Irving Park,WB,EB,,08/26/2008,41.953973,-87.69824,\"(41.953973, -87.69824)\"\nClark-Fullerton,NB,SB,,06/27/2007,41.925585,-87.64048,\"(41.925585, -87.64048)\"\nCicero-Harrison,SB,EB,,11/19/2009,41.873141,-87.745,\"(41.873141, -87.745)\"\nWestern-Van Buren,WB,SB,,05/29/2008,41.876083,-87.686271,\"(41.876083, -87.686271)\"\nHarlem-Belmont,NB,WB,,06/18/2007,41.937997,-87.806746,\"(41.937997, -87.806746)\"\nWestern-Touhy,SB,NB,,10/21/2008,42.012279,-87.690246,\"(42.012279, -87.690246)\"\nNarragansett-Irving Park,EB,WB,,10/14/2004,41.952916,-87.786558,\"(41.952916, -87.786558)\"\nAshland-Cortland,NB,EB,,02/26/2006,41.916128,-87.6678,\"(41.916128, -87.6678)\"\nCentral-Diversey,SB,WB,,08/18/2009,41.931278,-87.766248,\"(41.931278, -87.766248)\"\nWestern-Foster,SB,WB,,06/05/2007,41.97589,-87.689148,\"(41.97589, -87.689148)\"\nVincennes-87th,SB,EB,,11/11/2004,41.73605,-87.645174,\"(41.73605, -87.645174)\"\nKilpatrick-Irving Park,EB,WB,,10/21/2008,41.953446,-87.745578,\"(41.953446, -87.745578)\"\nKedzie-Belmont,SB,EB,NB,03/01/2004,41.93933,-87.707696,\"(41.93933, -87.707696)\"\nCicero-Lawrence,NB,SB,,11/02/2004,41.968029,-87.74772,\"(41.968029, -87.74772)\"\nCentral-Chicago,SB,EB,,05/28/2010,41.894852,-87.765395,\"(41.894852, -87.765395)\"\nKedzie-79th-Columbus,SB,EB,,01/10/2006,41.749842,-87.702396,\"(41.749842, -87.702396)\"\nKedzie-31st,SB,WB,,05/23/2008,41.837231,-87.704823,\"(41.837231, -87.704823)\"\nAshland-Fullerton,NB,SB,,06/08/2009,41.92515,-87.668144,\"(41.92515, -87.668144)\"\nDamen-Fullerton,EB,,,02/17/2006,41.925025,-87.677898,\"(41.925025, -87.677898)\"\nCentral-Belmont,SB,WB,,02/05/2009,41.938573,-87.766499,\"(41.938573, -87.766499)\"\nClark-Chicago,EB,WB,,10/22/2010,41.896635,-87.631243,\"(41.896635, -87.631243)\"\nElston-Addison,SB,EB,,10/19/2007,41.946622,-87.708841,\"(41.946622, -87.708841)\"\nKostner-Roosevelt,EB,NB,,03/18/2004,41.866031,-87.734965,\"(41.866031, -87.734965)\"\nSacramento-Lake,NB,SB,,10/20/2009,41.884075,-87.701291,\"(41.884075, -87.701291)\"\nStony Island-76th,NB,SB,,11/30/2008,41.756944,-87.58609,\"(41.756944, -87.58609)\"\nAustin-Diversey,WB,EB,,06/28/2008,41.931139,-87.775966,\"(41.931139, -87.775966)\"\nWestern-Devon,NB,SB,,07/31/2008,41.99773,-87.689881,\"(41.99773, -87.689881)\"\nHalsted-Roosevelt,WB,EB,,06/14/2008,41.867152,-87.646919,\"(41.867152, -87.646919)\"\nHalsted-Fullerton-Lincoln,NB,WB,,08/31/2008,41.925454,-87.64876,\"(41.925454, -87.64876)\"\nState-75th,NB,WB,,08/28/2009,41.75818,-87.624757,\"(41.75818, -87.624757)\"\nCentral-Lake,SB,EB,,07/17/2009,41.887729,-87.76512,\"(41.887729, -87.76512)\"\nAshland-Madison,NB,WB,,03/06/2004,41.881454,-87.666802,\"(41.881454, -87.666802)\"\nNarragansett-Fullerton,EB,WB,,11/14/2008,41.923676,-87.785441,\"(41.923676, -87.785441)\"\nNagle-Foster,WB,NB,,10/14/2004,41.975652,-87.787872,\"(41.975652, -87.787872)\"\nCicero-Archer,NB,WB,,11/13/2007,41.798659,-87.742927,\"(41.798659, -87.742927)\"\nCalifornia-Diversey,NB,WB,EB,01/31/2006,41.932096,-87.697616,\"(41.932096, -87.697616)\"\nLaramie-Irving Park,EB,WB,,01/27/2010,41.953299,-87.757148,\"(41.953299, -87.757148)\"\nElston-Irving Park,SB,EB,,08/12/2009,41.95373,-87.719084,\"(41.95373, -87.719084)\"\nWestern-Peterson,NB,SB,,02/26/2004,41.9905,-87.689671,\"(41.9905, -87.689671)\"\nKedzie-55th,SB,EB,,10/20/2009,41.793513,-87.703553,\"(41.793513, -87.703553)\"\nPulaski-Cermak,SB,WB,,10/11/2004,41.851546,-87.724757,\"(41.851546, -87.724757)\"\nAshland-Irving Park,NB,EB,,08/26/2008,41.954291,-87.669047,\"(41.954291, -87.669047)\"\nWestern-Marquette,SB,WB,,11/30/2008,41.771977,-87.683443,\"(41.771977, -87.683443)\"\nHalsted-North,NB,WB,,06/29/2009,41.91092,-87.648273,\"(41.91092, -87.648273)\"\nCentral-Irving Park,SB,EB,,06/30/2008,41.953183,-87.766998,\"(41.953183, -87.766998)\"\nPulaski-79th,SB,WB,,09/17/2009,41.749569,-87.721913,\"(41.749569, -87.721913)\"\nPulaski-Foster,SB,WB,,10/18/2007,41.975532,-87.728234,\"(41.975532, -87.728234)\"\nCicero-Chicago,NB,EB,,10/05/2007,41.895003,-87.745805,\"(41.895003, -87.745805)\"\nIllinois-Columbus,NB,SB,,10/28/2010,41.891002,-87.620224,\"(41.891002, -87.620224)\"\nCentral-Milwaukee,SB,SEB,,09/29/2017,41.976514,-87.768467,\"(41.976514, -87.768467)\"\nState-79th,WB,NB,,06/26/2009,41.750958,-87.624547,\"(41.750958, -87.624547)\"\nKostner-Ogden,SB,EB,,05/23/2008,41.847697,-87.734387,\"(41.847697, -87.734387)\"\nClark-Ridge,NB,SB,,07/23/2008,41.989697,-87.669985,\"(41.989697, -87.669985)\"\nPulaski-55th,SB,WB,,11/19/2004,41.793205,-87.72316,\"(41.793205, -87.72316)\"\nWestern-Montrose,NB,WB,,08/26/2008,41.961313,-87.688681,\"(41.961313, -87.688681)\"\nJeffery-95th,SB,EB,,11/26/2007,41.722468,-87.575353,\"(41.722468, -87.575353)\"\nHalsted-Madison,NB,SB,,06/14/2008,41.881776,-87.647361,\"(41.881776, -87.647361)\"\nBroadway-Foster,NB,EB,,10/18/2007,41.976323,-87.659867,\"(41.976323, -87.659867)\"\nHoman-Kimball-North,NB,EB,,10/05/2007,41.910053,-87.711879,\"(41.910053, -87.711879)\"\nWestern-35th,SB,NB,,10/11/2004,41.83028,-87.685033,\"(41.83028, -87.685033)\"\nHalsted-119th,SB,WB,,11/02/2004,41.677815,-87.641907,\"(41.677815, -87.641907)\"\nCicero-Addison,NB,SB,,11/30/2008,41.946124,-87.747064,\"(41.946124, -87.747064)\"\nHarlem-Addison,NB,EB,,06/21/2009,41.945264,-87.807006,\"(41.945264, -87.807006)\"\nCicero-Stevenson NB (SOUTH INTERSECTION),NB,SB,,04/29/2009,41.817092,-87.743477,\"(41.817092, -87.743477)\"\n"}},{"mime":"application/json","value":{"status":200,"statusText":"OK","headers":{"Date":"Sat, 06 Nov 2021 18:03:15 GMT","Expires":"Sat, 06 Nov 2021 18:08:15 GMT","Cache-Control":"max-age=300","Content-Type":"text/plain; charset=utf-8","Content-Length":"12201","X-XSS-Protection":"1; mode=block","X-Frame-Options":"deny","Connection":"close"},"config":{"timeout":10000,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","headers":{"Accept":"application/json, text/plain, */*","User-Agent":"axios/0.21.1"}},"request":{"method":"GET","httpVersion":"1.1","responseUrl":"https://raw.githubusercontent.com/RandomFractals/vscode-leaflet/main/data/csv/chicago-red-light-cameras.csv","timeout":10000,"headers":{}},"data":"Intersection,First Approach,Second Aproach,Third Approach,Go Live Date,Latitude,Longitude,Location\nMilwaukee-Devon,SB,WB,,02/28/2009,41.997407,-87.787921,\"(41.997407, -87.787921)\"\nCalifornia-Peterson,NB,EB,,06/29/2009,41.990442,-87.699401,\"(41.990442, -87.699401)\"\nCentral-Addison,SB,EB,,11/15/2010,41.945877,-87.766754,\"(41.945877, -87.766754)\"\nWestern-63rd,NB,EB,,11/12/2007,41.779214,-87.683638,\"(41.779214, -87.683638)\"\nHalsted-79th,NB,EB,,04/30/2008,41.750643,-87.644043,\"(41.750643, -87.644043)\"\nWacker-Lake,NB,SB,,02/19/2018,41.8857,-87.637,\"(41.8857, -87.637)\"\nLaramie-Fullerton,WB,NB,,06/28/2008,41.924106,-87.756147,\"(41.924106, -87.756147)\"\nLafayette-87th,SB,EB,,08/31/2009,41.736271,-87.625445,\"(41.736271, -87.625445)\"\nCanal-Roosevelt,NB,WB,,11/30/2008,41.867252,-87.639216,\"(41.867252, -87.639216)\"\nPulaski-Fullerton,WB,NB,,05/19/2007,41.924484,-87.726769,\"(41.924484, -87.726769)\"\nStony Island-Cornell-67th,NB,NB,,11/26/2007,41.77334,-87.586295,\"(41.77334, -87.586295)\"\nWestern-North,NB,EB,,11/26/2007,41.91032,-87.687222,\"(41.91032, -87.687222)\"\nCottage Grove-71st-South Chicago,NB,SB,,04/30/2008,41.765868,-87.605586,\"(41.765868, -87.605586)\"\nWentworth-Garfield,NB,WB,,05/08/2008,41.794201,-87.630518,\"(41.794201, -87.630518)\"\nState-63rd,SB,WB,,01/18/2006,41.780058,-87.625374,\"(41.780058, -87.625374)\"\nAshland-Division,NB,EB,,10/25/2007,41.903347,-87.667496,\"(41.903347, -87.667496)\"\nCicero-Fullerton,SB,WB,,02/25/2006,41.924237,-87.746302,\"(41.924237, -87.746302)\"\nCicero-Washington,NB,SB,,06/14/2008,41.881815,-87.745339,\"(41.881815, -87.745339)\"\nSacramento-Chicago,NB,WB,,09/18/2009,41.895591,-87.702455,\"(41.895591, -87.702455)\"\nCentral-Fullerton,SB,WB,,10/05/2007,41.92398,-87.765989,\"(41.92398, -87.765989)\"\nWestern-Lawrence,SB,EB,,07/31/2008,41.968614,-87.688906,\"(41.968614, -87.688906)\"\nPulaski-Irving Park,SB,WB,,05/19/2009,41.953646,-87.727617,\"(41.953646, -87.727617)\"\nKedzie-Armitage,SB,WB,,01/23/2009,41.917402,-87.706965,\"(41.917402, -87.706965)\"\nCicero-Diversey,NB,WB,,02/11/2010,41.931533,-87.746595,\"(41.931533, -87.746595)\"\nMilwaukee-Montrose,SB,WB,,03/11/2010,41.960632,-87.754476,\"(41.960632, -87.754476)\"\nWestern-Diversey-Elston,NB,WB,,07/18/2008,41.932179,-87.687883,\"(41.932179, -87.687883)\"\nWestern-Fullerton,NB,SB,,06/29/2009,41.9249,-87.687641,\"(41.9249, -87.687641)\"\nMilwaukee-Diversey,NB,EB,,06/29/2009,41.931984,-87.712251,\"(41.931984, -87.712251)\"\nKedzie-26th,NB,SB,,11/02/2010,41.844518,-87.705042,\"(41.844518, -87.705042)\"\nAshland-87th,SB,WB,,03/31/2007,41.735788,-87.663063,\"(41.735788, -87.663063)\"\nPulaski-Diversey,SB,NB,,05/15/2009,41.931791,-87.726979,\"(41.931791, -87.726979)\"\nKedzie-63rd,NB,WB,,11/26/2007,41.778972,-87.703138,\"(41.778972, -87.703138)\"\nMichigan-Ontario,SB,WB,,01/22/2018,41.893268,-87.624038,\"(41.893268, -87.624038)\"\nWestern-Cermak,SB,EB,,12/29/2009,41.852031,-87.685639,\"(41.852031, -87.685639)\"\nSheridan-Foster,SB,WB,,01/26/2008,41.976396,-87.654993,\"(41.976396, -87.654993)\"\nPulaski-Belmont,SB,EB,,05/19/2007,41.939094,-87.727185,\"(41.939094, -87.727185)\"\nPulaski-North,NB,WB,,11/30/2008,41.909886,-87.72633,\"(41.909886, -87.72633)\"\nStony Island-79th-South Chicago,SB,WB,NB,05/07/2007,41.751506,-87.585823,\"(41.751506, -87.585823)\"\nDamen-63rd,NB,SB,,05/31/2008,41.779315,-87.673906,\"(41.779315, -87.673906)\"\nCicero-North,EB,WB,,05/31/2008,41.909626,-87.746112,\"(41.909626, -87.746112)\"\nBroadway-Sheridan-Devon,SB,EB,,10/18/2007,41.99819,-87.660545,\"(41.99819, -87.660545)\"\nKedzie-47th,NB,WB,,03/30/2008,41.808115,-87.703974,\"(41.808115, -87.703974)\"\nPulaski-Archer-50th,EB,WB,,10/31/2007,41.802317,-87.723422,\"(41.802317, -87.723422)\"\nElston-Lawrence,SB,WB,,06/08/2009,41.968108,-87.740163,\"(41.968108, -87.740163)\"\nDamen-Division,EB,WB,,12/29/2009,41.903191,-87.677258,\"(41.903191, -87.677258)\"\nClark-Irving Park,EB,NB,,07/22/2008,41.954378,-87.662248,\"(41.954378, -87.662248)\"\nAshland-71st,NB,WB,,10/11/2004,41.76491,-87.663794,\"(41.76491, -87.663794)\"\nHamlin-Lake,NB,SB,,05/31/2008,41.885203,-87.720919,\"(41.885203, -87.720919)\"\nAustin-Irving Park,NB,EB,,06/30/2008,41.953055,-87.776775,\"(41.953055, -87.776775)\"\nPulaski-63rd,SB,EB,,03/31/2007,41.778658,-87.722759,\"(41.778658, -87.722759)\"\nLaramie-Madison,EB,WB,,05/11/2011,41.880371,-87.755065,\"(41.880371, -87.755065)\"\nOsceola-Touhy,EB,WB,,10/21/2008,42.011553,-87.812251,\"(42.011553, -87.812251)\"\nPulaski-Armitage,WB,EB,,05/31/2008,41.917165,-87.726559,\"(41.917165, -87.726559)\"\nCalifornia-Devon,NB,EB,,07/31/2008,41.997559,-87.699643,\"(41.997559, -87.699643)\"\nPulaski-Chicago,SB,EB,,02/20/2010,41.895367,-87.726078,\"(41.895367, -87.726078)\"\nDamen-Elston,SB,,,02/17/2006,41.925816,-87.677898,\"(41.925816, -87.677898)\"\nWestern-Madison,NB,WB,,06/01/2004,41.881161,-87.686432,\"(41.881161, -87.686432)\"\nDr Martin Luther King-31st,NB,EB,,06/22/2008,41.838419,-87.617465,\"(41.838419, -87.617465)\"\nPulaski-Roosevelt,NB,WB,,07/17/2009,41.866172,-87.725169,\"(41.866172, -87.725169)\"\nAshland-95th,SB,EB,,06/26/2009,41.721214,-87.662684,\"(41.721214, -87.662684)\"\nHalsted-95th,NB,SB,,04/30/2008,41.721458,-87.643212,\"(41.721458, -87.643212)\"\nDamen-Diversey-Clybourn,SB,WB,,06/30/2008,41.932285,-87.678136,\"(41.932285, -87.678136)\"\nPulaski-Division,NB,SB,,07/22/2009,41.902671,-87.726303,\"(41.902671, -87.726303)\"\nKostner-Grand-North,EB,NB,SB,03/11/2004,41.909754,-87.736262,\"(41.909754, -87.736262)\"\nWestern-Addison,NB,EB,,06/08/2009,41.946731,-87.688258,\"(41.946731, -87.688258)\"\nCicero-47th,SB,WB,,03/31/2008,41.807623,-87.743153,\"(41.807623, -87.743153)\"\nHamlin-Madison,NB,EB,,04/29/2009,41.880789,-87.720752,\"(41.880789, -87.720752)\"\nMichigan-Jackson,NB,EB,,01/22/2018,41.878246,-87.624087,\"(41.878246, -87.624087)\"\nSheridan-Hollywood,WB,EB,,10/18/2007,41.985549,-87.655242,\"(41.985549, -87.655242)\"\nNorthwest Hwy-Foster,SEB,EB,,09/29/2017,41.975688,-87.769261,\"(41.975688, -87.769261)\"\nHalsted-99th,NB,EB,,01/01/2006,41.714215,-87.643004,\"(41.714215, -87.643004)\"\nCicero-Armitage,EB,NB,,11/14/2008,41.916931,-87.746111,\"(41.916931, -87.746111)\"\nAshland-Lawrence,SB,EB,,08/27/2008,41.968876,-87.66944,\"(41.968876, -87.66944)\"\nLaSalle-Kinzie,NB,EB,,04/30/2004,41.889187,-87.632526,\"(41.889187, -87.632526)\"\nWestern-Chicago,NB,EB,,05/07/2007,41.895743,-87.686843,\"(41.895743, -87.686843)\"\nAustin-Addison,EB,NB,,06/28/2008,41.945771,-87.776504,\"(41.945771, -87.776504)\"\nHalsted-Division,NB,WB,,04/07/2004,41.903636,-87.648094,\"(41.903636, -87.648094)\"\nHalsted-111th,SB,WB,,01/01/2006,41.692355,-87.642377,\"(41.692355, -87.642377)\"\nLake Shore-Belmont,SB,EB,,06/22/2008,41.94024,-87.638696,\"(41.94024, -87.638696)\"\nWestern-79th,NB,WB,,05/07/2007,41.750101,-87.682847,\"(41.750101, -87.682847)\"\nWestern-47th,SB,NB,,11/29/2004,41.808426,-87.684425,\"(41.808426, -87.684425)\"\nPulaski-Lawrence,SB,EB,,07/31/2008,41.968242,-87.728027,\"(41.968242, -87.728027)\"\nWestern-55th,SB,EB,,11/01/2003,41.793877,-87.68404,\"(41.793877, -87.68404)\"\nKedzie-71st,SB,WB,,09/17/2009,41.76439,-87.702811,\"(41.76439, -87.702811)\"\nCicero-Peterson,SB,WB,,08/26/2008,41.989898,-87.748325,\"(41.989898, -87.748325)\"\nCalifornia-Irving Park,WB,EB,,08/26/2008,41.953973,-87.69824,\"(41.953973, -87.69824)\"\nClark-Fullerton,NB,SB,,06/27/2007,41.925585,-87.64048,\"(41.925585, -87.64048)\"\nCicero-Harrison,SB,EB,,11/19/2009,41.873141,-87.745,\"(41.873141, -87.745)\"\nWestern-Van Buren,WB,SB,,05/29/2008,41.876083,-87.686271,\"(41.876083, -87.686271)\"\nHarlem-Belmont,NB,WB,,06/18/2007,41.937997,-87.806746,\"(41.937997, -87.806746)\"\nWestern-Touhy,SB,NB,,10/21/2008,42.012279,-87.690246,\"(42.012279, -87.690246)\"\nNarragansett-Irving Park,EB,WB,,10/14/2004,41.952916,-87.786558,\"(41.952916, -87.786558)\"\nAshland-Cortland,NB,EB,,02/26/2006,41.916128,-87.6678,\"(41.916128, -87.6678)\"\nCentral-Diversey,SB,WB,,08/18/2009,41.931278,-87.766248,\"(41.931278, -87.766248)\"\nWestern-Foster,SB,WB,,06/05/2007,41.97589,-87.689148,\"(41.97589, -87.689148)\"\nVincennes-87th,SB,EB,,11/11/2004,41.73605,-87.645174,\"(41.73605, -87.645174)\"\nKilpatrick-Irving Park,EB,WB,,10/21/2008,41.953446,-87.745578,\"(41.953446, -87.745578)\"\nKedzie-Belmont,SB,EB,NB,03/01/2004,41.93933,-87.707696,\"(41.93933, -87.707696)\"\nCicero-Lawrence,NB,SB,,11/02/2004,41.968029,-87.74772,\"(41.968029, -87.74772)\"\nCentral-Chicago,SB,EB,,05/28/2010,41.894852,-87.765395,\"(41.894852, -87.765395)\"\nKedzie-79th-Columbus,SB,EB,,01/10/2006,41.749842,-87.702396,\"(41.749842, -87.702396)\"\nKedzie-31st,SB,WB,,05/23/2008,41.837231,-87.704823,\"(41.837231, -87.704823)\"\nAshland-Fullerton,NB,SB,,06/08/2009,41.92515,-87.668144,\"(41.92515, -87.668144)\"\nDamen-Fullerton,EB,,,02/17/2006,41.925025,-87.677898,\"(41.925025, -87.677898)\"\nCentral-Belmont,SB,WB,,02/05/2009,41.938573,-87.766499,\"(41.938573, -87.766499)\"\nClark-Chicago,EB,WB,,10/22/2010,41.896635,-87.631243,\"(41.896635, -87.631243)\"\nElston-Addison,SB,EB,,10/19/2007,41.946622,-87.708841,\"(41.946622, -87.708841)\"\nKostner-Roosevelt,EB,NB,,03/18/2004,41.866031,-87.734965,\"(41.866031, -87.734965)\"\nSacramento-Lake,NB,SB,,10/20/2009,41.884075,-87.701291,\"(41.884075, -87.701291)\"\nStony Island-76th,NB,SB,,11/30/2008,41.756944,-87.58609,\"(41.756944, -87.58609)\"\nAustin-Diversey,WB,EB,,06/28/2008,41.931139,-87.775966,\"(41.931139, -87.775966)\"\nWestern-Devon,NB,SB,,07/31/2008,41.99773,-87.689881,\"(41.99773, -87.689881)\"\nHalsted-Roosevelt,WB,EB,,06/14/2008,41.867152,-87.646919,\"(41.867152, -87.646919)\"\nHalsted-Fullerton-Lincoln,NB,WB,,08/31/2008,41.925454,-87.64876,\"(41.925454, -87.64876)\"\nState-75th,NB,WB,,08/28/2009,41.75818,-87.624757,\"(41.75818, -87.624757)\"\nCentral-Lake,SB,EB,,07/17/2009,41.887729,-87.76512,\"(41.887729, -87.76512)\"\nAshland-Madison,NB,WB,,03/06/2004,41.881454,-87.666802,\"(41.881454, -87.666802)\"\nNarragansett-Fullerton,EB,WB,,11/14/2008,41.923676,-87.785441,\"(41.923676, -87.785441)\"\nNagle-Foster,WB,NB,,10/14/2004,41.975652,-87.787872,\"(41.975652, -87.787872)\"\nCicero-Archer,NB,WB,,11/13/2007,41.798659,-87.742927,\"(41.798659, -87.742927)\"\nCalifornia-Diversey,NB,WB,EB,01/31/2006,41.932096,-87.697616,\"(41.932096, -87.697616)\"\nLaramie-Irving Park,EB,WB,,01/27/2010,41.953299,-87.757148,\"(41.953299, -87.757148)\"\nElston-Irving Park,SB,EB,,08/12/2009,41.95373,-87.719084,\"(41.95373, -87.719084)\"\nWestern-Peterson,NB,SB,,02/26/2004,41.9905,-87.689671,\"(41.9905, -87.689671)\"\nKedzie-55th,SB,EB,,10/20/2009,41.793513,-87.703553,\"(41.793513, -87.703553)\"\nPulaski-Cermak,SB,WB,,10/11/2004,41.851546,-87.724757,\"(41.851546, -87.724757)\"\nAshland-Irving Park,NB,EB,,08/26/2008,41.954291,-87.669047,\"(41.954291, -87.669047)\"\nWestern-Marquette,SB,WB,,11/30/2008,41.771977,-87.683443,\"(41.771977, -87.683443)\"\nHalsted-North,NB,WB,,06/29/2009,41.91092,-87.648273,\"(41.91092, -87.648273)\"\nCentral-Irving Park,SB,EB,,06/30/2008,41.953183,-87.766998,\"(41.953183, -87.766998)\"\nPulaski-79th,SB,WB,,09/17/2009,41.749569,-87.721913,\"(41.749569, -87.721913)\"\nPulaski-Foster,SB,WB,,10/18/2007,41.975532,-87.728234,\"(41.975532, -87.728234)\"\nCicero-Chicago,NB,EB,,10/05/2007,41.895003,-87.745805,\"(41.895003, -87.745805)\"\nIllinois-Columbus,NB,SB,,10/28/2010,41.891002,-87.620224,\"(41.891002, -87.620224)\"\nCentral-Milwaukee,SB,SEB,,09/29/2017,41.976514,-87.768467,\"(41.976514, -87.768467)\"\nState-79th,WB,NB,,06/26/2009,41.750958,-87.624547,\"(41.750958, -87.624547)\"\nKostner-Ogden,SB,EB,,05/23/2008,41.847697,-87.734387,\"(41.847697, -87.734387)\"\nClark-Ridge,NB,SB,,07/23/2008,41.989697,-87.669985,\"(41.989697, -87.669985)\"\nPulaski-55th,SB,WB,,11/19/2004,41.793205,-87.72316,\"(41.793205, -87.72316)\"\nWestern-Montrose,NB,WB,,08/26/2008,41.961313,-87.688681,\"(41.961313, -87.688681)\"\nJeffery-95th,SB,EB,,11/26/2007,41.722468,-87.575353,\"(41.722468, -87.575353)\"\nHalsted-Madison,NB,SB,,06/14/2008,41.881776,-87.647361,\"(41.881776, -87.647361)\"\nBroadway-Foster,NB,EB,,10/18/2007,41.976323,-87.659867,\"(41.976323, -87.659867)\"\nHoman-Kimball-North,NB,EB,,10/05/2007,41.910053,-87.711879,\"(41.910053, -87.711879)\"\nWestern-35th,SB,NB,,10/11/2004,41.83028,-87.685033,\"(41.83028, -87.685033)\"\nHalsted-119th,SB,WB,,11/02/2004,41.677815,-87.641907,\"(41.677815, -87.641907)\"\nCicero-Addison,NB,SB,,11/30/2008,41.946124,-87.747064,\"(41.946124, -87.747064)\"\nHarlem-Addison,NB,EB,,06/21/2009,41.945264,-87.807006,\"(41.945264, -87.807006)\"\nCicero-Stevenson NB (SOUTH INTERSECTION),NB,SB,,04/29/2009,41.817092,-87.743477,\"(41.817092, -87.743477)\"\n"}},{"mime":"text/html","value":"Intersection,First Approach,Second Aproach,Third Approach,Go Live Date,Latitude,Longitude,Location\nMilwaukee-Devon,SB,WB,,02/28/2009,41.997407,-87.787921,\"(41.997407, -87.787921)\"\nCalifornia-Peterson,NB,EB,,06/29/2009,41.990442,-87.699401,\"(41.990442, -87.699401)\"\nCentral-Addison,SB,EB,,11/15/2010,41.945877,-87.766754,\"(41.945877, -87.766754)\"\nWestern-63rd,NB,EB,,11/12/2007,41.779214,-87.683638,\"(41.779214, -87.683638)\"\nHalsted-79th,NB,EB,,04/30/2008,41.750643,-87.644043,\"(41.750643, -87.644043)\"\nWacker-Lake,NB,SB,,02/19/2018,41.8857,-87.637,\"(41.8857, -87.637)\"\nLaramie-Fullerton,WB,NB,,06/28/2008,41.924106,-87.756147,\"(41.924106, -87.756147)\"\nLafayette-87th,SB,EB,,08/31/2009,41.736271,-87.625445,\"(41.736271, -87.625445)\"\nCanal-Roosevelt,NB,WB,,11/30/2008,41.867252,-87.639216,\"(41.867252, -87.639216)\"\nPulaski-Fullerton,WB,NB,,05/19/2007,41.924484,-87.726769,\"(41.924484, -87.726769)\"\nStony Island-Cornell-67th,NB,NB,,11/26/2007,41.77334,-87.586295,\"(41.77334, -87.586295)\"\nWestern-North,NB,EB,,11/26/2007,41.91032,-87.687222,\"(41.91032, -87.687222)\"\nCottage Grove-71st-South Chicago,NB,SB,,04/30/2008,41.765868,-87.605586,\"(41.765868, -87.605586)\"\nWentworth-Garfield,NB,WB,,05/08/2008,41.794201,-87.630518,\"(41.794201, -87.630518)\"\nState-63rd,SB,WB,,01/18/2006,41.780058,-87.625374,\"(41.780058, -87.625374)\"\nAshland-Division,NB,EB,,10/25/2007,41.903347,-87.667496,\"(41.903347, -87.667496)\"\nCicero-Fullerton,SB,WB,,02/25/2006,41.924237,-87.746302,\"(41.924237, -87.746302)\"\nCicero-Washington,NB,SB,,06/14/2008,41.881815,-87.745339,\"(41.881815, -87.745339)\"\nSacramento-Chicago,NB,WB,,09/18/2009,41.895591,-87.702455,\"(41.895591, -87.702455)\"\nCentral-Fullerton,SB,WB,,10/05/2007,41.92398,-87.765989,\"(41.92398, -87.765989)\"\nWestern-Lawrence,SB,EB,,07/31/2008,41.968614,-87.688906,\"(41.968614, -87.688906)\"\nPulaski-Irving Park,SB,WB,,05/19/2009,41.953646,-87.727617,\"(41.953646, -87.727617)\"\nKedzie-Armitage,SB,WB,,01/23/2009,41.917402,-87.706965,\"(41.917402, -87.706965)\"\nCicero-Diversey,NB,WB,,02/11/2010,41.931533,-87.746595,\"(41.931533, -87.746595)\"\nMilwaukee-Montrose,SB,WB,,03/11/2010,41.960632,-87.754476,\"(41.960632, -87.754476)\"\nWestern-Diversey-Elston,NB,WB,,07/18/2008,41.932179,-87.687883,\"(41.932179, -87.687883)\"\nWestern-Fullerton,NB,SB,,06/29/2009,41.9249,-87.687641,\"(41.9249, -87.687641)\"\nMilwaukee-Diversey,NB,EB,,06/29/2009,41.931984,-87.712251,\"(41.931984, -87.712251)\"\nKedzie-26th,NB,SB,,11/02/2010,41.844518,-87.705042,\"(41.844518, -87.705042)\"\nAshland-87th,SB,WB,,03/31/2007,41.735788,-87.663063,\"(41.735788, -87.663063)\"\nPulaski-Diversey,SB,NB,,05/15/2009,41.931791,-87.726979,\"(41.931791, -87.726979)\"\nKedzie-63rd,NB,WB,,11/26/2007,41.778972,-87.703138,\"(41.778972, -87.703138)\"\nMichigan-Ontario,SB,WB,,01/22/2018,41.893268,-87.624038,\"(41.893268, -87.624038)\"\nWestern-Cermak,SB,EB,,12/29/2009,41.852031,-87.685639,\"(41.852031, -87.685639)\"\nSheridan-Foster,SB,WB,,01/26/2008,41.976396,-87.654993,\"(41.976396, -87.654993)\"\nPulaski-Belmont,SB,EB,,05/19/2007,41.939094,-87.727185,\"(41.939094, -87.727185)\"\nPulaski-North,NB,WB,,11/30/2008,41.909886,-87.72633,\"(41.909886, -87.72633)\"\nStony Island-79th-South Chicago,SB,WB,NB,05/07/2007,41.751506,-87.585823,\"(41.751506, -87.585823)\"\nDamen-63rd,NB,SB,,05/31/2008,41.779315,-87.673906,\"(41.779315, -87.673906)\"\nCicero-North,EB,WB,,05/31/2008,41.909626,-87.746112,\"(41.909626, -87.746112)\"\nBroadway-Sheridan-Devon,SB,EB,,10/18/2007,41.99819,-87.660545,\"(41.99819, -87.660545)\"\nKedzie-47th,NB,WB,,03/30/2008,41.808115,-87.703974,\"(41.808115, -87.703974)\"\nPulaski-Archer-50th,EB,WB,,10/31/2007,41.802317,-87.723422,\"(41.802317, -87.723422)\"\nElston-Lawrence,SB,WB,,06/08/2009,41.968108,-87.740163,\"(41.968108, -87.740163)\"\nDamen-Division,EB,WB,,12/29/2009,41.903191,-87.677258,\"(41.903191, -87.677258)\"\nClark-Irving Park,EB,NB,,07/22/2008,41.954378,-87.662248,\"(41.954378, -87.662248)\"\nAshland-71st,NB,WB,,10/11/2004,41.76491,-87.663794,\"(41.76491, -87.663794)\"\nHamlin-Lake,NB,SB,,05/31/2008,41.885203,-87.720919,\"(41.885203, -87.720919)\"\nAustin-Irving Park,NB,EB,,06/30/2008,41.953055,-87.776775,\"(41.953055, -87.776775)\"\nPulaski-63rd,SB,EB,,03/31/2007,41.778658,-87.722759,\"(41.778658, -87.722759)\"\nLaramie-Madison,EB,WB,,05/11/2011,41.880371,-87.755065,\"(41.880371, -87.755065)\"\nOsceola-Touhy,EB,WB,,10/21/2008,42.011553,-87.812251,\"(42.011553, -87.812251)\"\nPulaski-Armitage,WB,EB,,05/31/2008,41.917165,-87.726559,\"(41.917165, -87.726559)\"\nCalifornia-Devon,NB,EB,,07/31/2008,41.997559,-87.699643,\"(41.997559, -87.699643)\"\nPulaski-Chicago,SB,EB,,02/20/2010,41.895367,-87.726078,\"(41.895367, -87.726078)\"\nDamen-Elston,SB,,,02/17/2006,41.925816,-87.677898,\"(41.925816, -87.677898)\"\nWestern-Madison,NB,WB,,06/01/2004,41.881161,-87.686432,\"(41.881161, -87.686432)\"\nDr Martin Luther King-31st,NB,EB,,06/22/2008,41.838419,-87.617465,\"(41.838419, -87.617465)\"\nPulaski-Roosevelt,NB,WB,,07/17/2009,41.866172,-87.725169,\"(41.866172, -87.725169)\"\nAshland-95th,SB,EB,,06/26/2009,41.721214,-87.662684,\"(41.721214, -87.662684)\"\nHalsted-95th,NB,SB,,04/30/2008,41.721458,-87.643212,\"(41.721458, -87.643212)\"\nDamen-Diversey-Clybourn,SB,WB,,06/30/2008,41.932285,-87.678136,\"(41.932285, -87.678136)\"\nPulaski-Division,NB,SB,,07/22/2009,41.902671,-87.726303,\"(41.902671, -87.726303)\"\nKostner-Grand-North,EB,NB,SB,03/11/2004,41.909754,-87.736262,\"(41.909754, -87.736262)\"\nWestern-Addison,NB,EB,,06/08/2009,41.946731,-87.688258,\"(41.946731, -87.688258)\"\nCicero-47th,SB,WB,,03/31/2008,41.807623,-87.743153,\"(41.807623, -87.743153)\"\nHamlin-Madison,NB,EB,,04/29/2009,41.880789,-87.720752,\"(41.880789, -87.720752)\"\nMichigan-Jackson,NB,EB,,01/22/2018,41.878246,-87.624087,\"(41.878246, -87.624087)\"\nSheridan-Hollywood,WB,EB,,10/18/2007,41.985549,-87.655242,\"(41.985549, -87.655242)\"\nNorthwest Hwy-Foster,SEB,EB,,09/29/2017,41.975688,-87.769261,\"(41.975688, -87.769261)\"\nHalsted-99th,NB,EB,,01/01/2006,41.714215,-87.643004,\"(41.714215, -87.643004)\"\nCicero-Armitage,EB,NB,,11/14/2008,41.916931,-87.746111,\"(41.916931, -87.746111)\"\nAshland-Lawrence,SB,EB,,08/27/2008,41.968876,-87.66944,\"(41.968876, -87.66944)\"\nLaSalle-Kinzie,NB,EB,,04/30/2004,41.889187,-87.632526,\"(41.889187, -87.632526)\"\nWestern-Chicago,NB,EB,,05/07/2007,41.895743,-87.686843,\"(41.895743, -87.686843)\"\nAustin-Addison,EB,NB,,06/28/2008,41.945771,-87.776504,\"(41.945771, -87.776504)\"\nHalsted-Division,NB,WB,,04/07/2004,41.903636,-87.648094,\"(41.903636, -87.648094)\"\nHalsted-111th,SB,WB,,01/01/2006,41.692355,-87.642377,\"(41.692355, -87.642377)\"\nLake Shore-Belmont,SB,EB,,06/22/2008,41.94024,-87.638696,\"(41.94024, -87.638696)\"\nWestern-79th,NB,WB,,05/07/2007,41.750101,-87.682847,\"(41.750101, -87.682847)\"\nWestern-47th,SB,NB,,11/29/2004,41.808426,-87.684425,\"(41.808426, -87.684425)\"\nPulaski-Lawrence,SB,EB,,07/31/2008,41.968242,-87.728027,\"(41.968242, -87.728027)\"\nWestern-55th,SB,EB,,11/01/2003,41.793877,-87.68404,\"(41.793877, -87.68404)\"\nKedzie-71st,SB,WB,,09/17/2009,41.76439,-87.702811,\"(41.76439, -87.702811)\"\nCicero-Peterson,SB,WB,,08/26/2008,41.989898,-87.748325,\"(41.989898, -87.748325)\"\nCalifornia-Irving Park,WB,EB,,08/26/2008,41.953973,-87.69824,\"(41.953973, -87.69824)\"\nClark-Fullerton,NB,SB,,06/27/2007,41.925585,-87.64048,\"(41.925585, -87.64048)\"\nCicero-Harrison,SB,EB,,11/19/2009,41.873141,-87.745,\"(41.873141, -87.745)\"\nWestern-Van Buren,WB,SB,,05/29/2008,41.876083,-87.686271,\"(41.876083, -87.686271)\"\nHarlem-Belmont,NB,WB,,06/18/2007,41.937997,-87.806746,\"(41.937997, -87.806746)\"\nWestern-Touhy,SB,NB,,10/21/2008,42.012279,-87.690246,\"(42.012279, -87.690246)\"\nNarragansett-Irving Park,EB,WB,,10/14/2004,41.952916,-87.786558,\"(41.952916, -87.786558)\"\nAshland-Cortland,NB,EB,,02/26/2006,41.916128,-87.6678,\"(41.916128, -87.6678)\"\nCentral-Diversey,SB,WB,,08/18/2009,41.931278,-87.766248,\"(41.931278, -87.766248)\"\nWestern-Foster,SB,WB,,06/05/2007,41.97589,-87.689148,\"(41.97589, -87.689148)\"\nVincennes-87th,SB,EB,,11/11/2004,41.73605,-87.645174,\"(41.73605, -87.645174)\"\nKilpatrick-Irving Park,EB,WB,,10/21/2008,41.953446,-87.745578,\"(41.953446, -87.745578)\"\nKedzie-Belmont,SB,EB,NB,03/01/2004,41.93933,-87.707696,\"(41.93933, -87.707696)\"\nCicero-Lawrence,NB,SB,,11/02/2004,41.968029,-87.74772,\"(41.968029, -87.74772)\"\nCentral-Chicago,SB,EB,,05/28/2010,41.894852,-87.765395,\"(41.894852, -87.765395)\"\nKedzie-79th-Columbus,SB,EB,,01/10/2006,41.749842,-87.702396,\"(41.749842, -87.702396)\"\nKedzie-31st,SB,WB,,05/23/2008,41.837231,-87.704823,\"(41.837231, -87.704823)\"\nAshland-Fullerton,NB,SB,,06/08/2009,41.92515,-87.668144,\"(41.92515, -87.668144)\"\nDamen-Fullerton,EB,,,02/17/2006,41.925025,-87.677898,\"(41.925025, -87.677898)\"\nCentral-Belmont,SB,WB,,02/05/2009,41.938573,-87.766499,\"(41.938573, -87.766499)\"\nClark-Chicago,EB,WB,,10/22/2010,41.896635,-87.631243,\"(41.896635, -87.631243)\"\nElston-Addison,SB,EB,,10/19/2007,41.946622,-87.708841,\"(41.946622, -87.708841)\"\nKostner-Roosevelt,EB,NB,,03/18/2004,41.866031,-87.734965,\"(41.866031, -87.734965)\"\nSacramento-Lake,NB,SB,,10/20/2009,41.884075,-87.701291,\"(41.884075, -87.701291)\"\nStony Island-76th,NB,SB,,11/30/2008,41.756944,-87.58609,\"(41.756944, -87.58609)\"\nAustin-Diversey,WB,EB,,06/28/2008,41.931139,-87.775966,\"(41.931139, -87.775966)\"\nWestern-Devon,NB,SB,,07/31/2008,41.99773,-87.689881,\"(41.99773, -87.689881)\"\nHalsted-Roosevelt,WB,EB,,06/14/2008,41.867152,-87.646919,\"(41.867152, -87.646919)\"\nHalsted-Fullerton-Lincoln,NB,WB,,08/31/2008,41.925454,-87.64876,\"(41.925454, -87.64876)\"\nState-75th,NB,WB,,08/28/2009,41.75818,-87.624757,\"(41.75818, -87.624757)\"\nCentral-Lake,SB,EB,,07/17/2009,41.887729,-87.76512,\"(41.887729, -87.76512)\"\nAshland-Madison,NB,WB,,03/06/2004,41.881454,-87.666802,\"(41.881454, -87.666802)\"\nNarragansett-Fullerton,EB,WB,,11/14/2008,41.923676,-87.785441,\"(41.923676, -87.785441)\"\nNagle-Foster,WB,NB,,10/14/2004,41.975652,-87.787872,\"(41.975652, -87.787872)\"\nCicero-Archer,NB,WB,,11/13/2007,41.798659,-87.742927,\"(41.798659, -87.742927)\"\nCalifornia-Diversey,NB,WB,EB,01/31/2006,41.932096,-87.697616,\"(41.932096, -87.697616)\"\nLaramie-Irving Park,EB,WB,,01/27/2010,41.953299,-87.757148,\"(41.953299, -87.757148)\"\nElston-Irving Park,SB,EB,,08/12/2009,41.95373,-87.719084,\"(41.95373, -87.719084)\"\nWestern-Peterson,NB,SB,,02/26/2004,41.9905,-87.689671,\"(41.9905, -87.689671)\"\nKedzie-55th,SB,EB,,10/20/2009,41.793513,-87.703553,\"(41.793513, -87.703553)\"\nPulaski-Cermak,SB,WB,,10/11/2004,41.851546,-87.724757,\"(41.851546, -87.724757)\"\nAshland-Irving Park,NB,EB,,08/26/2008,41.954291,-87.669047,\"(41.954291, -87.669047)\"\nWestern-Marquette,SB,WB,,11/30/2008,41.771977,-87.683443,\"(41.771977, -87.683443)\"\nHalsted-North,NB,WB,,06/29/2009,41.91092,-87.648273,\"(41.91092, -87.648273)\"\nCentral-Irving Park,SB,EB,,06/30/2008,41.953183,-87.766998,\"(41.953183, -87.766998)\"\nPulaski-79th,SB,WB,,09/17/2009,41.749569,-87.721913,\"(41.749569, -87.721913)\"\nPulaski-Foster,SB,WB,,10/18/2007,41.975532,-87.728234,\"(41.975532, -87.728234)\"\nCicero-Chicago,NB,EB,,10/05/2007,41.895003,-87.745805,\"(41.895003, -87.745805)\"\nIllinois-Columbus,NB,SB,,10/28/2010,41.891002,-87.620224,\"(41.891002, -87.620224)\"\nCentral-Milwaukee,SB,SEB,,09/29/2017,41.976514,-87.768467,\"(41.976514, -87.768467)\"\nState-79th,WB,NB,,06/26/2009,41.750958,-87.624547,\"(41.750958, -87.624547)\"\nKostner-Ogden,SB,EB,,05/23/2008,41.847697,-87.734387,\"(41.847697, -87.734387)\"\nClark-Ridge,NB,SB,,07/23/2008,41.989697,-87.669985,\"(41.989697, -87.669985)\"\nPulaski-55th,SB,WB,,11/19/2004,41.793205,-87.72316,\"(41.793205, -87.72316)\"\nWestern-Montrose,NB,WB,,08/26/2008,41.961313,-87.688681,\"(41.961313, -87.688681)\"\nJeffery-95th,SB,EB,,11/26/2007,41.722468,-87.575353,\"(41.722468, -87.575353)\"\nHalsted-Madison,NB,SB,,06/14/2008,41.881776,-87.647361,\"(41.881776, -87.647361)\"\nBroadway-Foster,NB,EB,,10/18/2007,41.976323,-87.659867,\"(41.976323, -87.659867)\"\nHoman-Kimball-North,NB,EB,,10/05/2007,41.910053,-87.711879,\"(41.910053, -87.711879)\"\nWestern-35th,SB,NB,,10/11/2004,41.83028,-87.685033,\"(41.83028, -87.685033)\"\nHalsted-119th,SB,WB,,11/02/2004,41.677815,-87.641907,\"(41.677815, -87.641907)\"\nCicero-Addison,NB,SB,,11/30/2008,41.946124,-87.747064,\"(41.946124, -87.747064)\"\nHarlem-Addison,NB,EB,,06/21/2009,41.945264,-87.807006,\"(41.945264, -87.807006)\"\nCicero-Stevenson NB (SOUTH INTERSECTION),NB,SB,,04/29/2009,41.817092,-87.743477,\"(41.817092, -87.743477)\"\n"}]}] -------------------------------------------------------------------------------- /notebooks/usa-airports-net.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "source": [ 6 | "# USA Airports .NET Interactive Notebook 📓" 7 | ], 8 | "metadata": {} 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": null, 13 | "source": [ 14 | "using System.Net.Http;\r\n", 15 | "var dataUrl = \"https://raw.githubusercontent.com/RandomFractals/vscode-leaflet/main/data/geojson/usa-airports.geojson\";\r\n", 16 | "var data = await new HttpClient().GetStringAsync(dataUrl);\r\n", 17 | "data" 18 | ], 19 | "outputs": [], 20 | "metadata": { 21 | "dotnet_interactive": { 22 | "language": "csharp" 23 | } 24 | } 25 | } 26 | ], 27 | "metadata": { 28 | "orig_nbformat": 4, 29 | "language_info": { 30 | "file_extension": ".cs", 31 | "mimetype": "text/x-csharp", 32 | "name": "C#", 33 | "pygments_lexer": "csharp", 34 | "version": "9.0" 35 | }, 36 | "kernelspec": { 37 | "display_name": ".NET (C#)", 38 | "language": "C#", 39 | "name": ".net-csharp" 40 | } 41 | }, 42 | "nbformat": 4, 43 | "nbformat_minor": 2 44 | } -------------------------------------------------------------------------------- /notebooks/usa-state-capitals-typescript.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "source": [ 6 | "# USA State Capitals TypeScript Notebook 📓" 7 | ], 8 | "metadata": {} 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": null, 13 | "source": [ 14 | "import fs from 'fs';\r\n", 15 | "const geoJson = fs.readFileSync('../data/geojson/usa-state-capitals.geojson', 'utf-8');\r\n", 16 | "geoJson" 17 | ], 18 | "outputs": [], 19 | "metadata": {} 20 | } 21 | ], 22 | "metadata": { 23 | "orig_nbformat": 4, 24 | "language_info": { 25 | "name": "typescript", 26 | "version": "3.7.2", 27 | "mimetype": "text/typescript", 28 | "file_extension": ".ts", 29 | "codemirror_mode": { 30 | "mode": "typescript", 31 | "name": "javascript", 32 | "typescript": true 33 | } 34 | }, 35 | "kernelspec": { 36 | "name": "typescript", 37 | "display_name": "TypeScript", 38 | "language": "typescript" 39 | } 40 | }, 41 | "nbformat": 4, 42 | "nbformat_minor": 2 43 | } -------------------------------------------------------------------------------- /notebooks/world-countries.restbook: -------------------------------------------------------------------------------- 1 | [{"kind":1,"language":"markdown","value":"# World Countries REST Book 📓\r\n\r\nData Source: [https://github.com/gavinr/world-countries-centroids](https://github.com/gavinr/world-countries-centroids)","outputs":[]},{"kind":2,"language":"rest-book","value":"GET https://raw.githubusercontent.com/RandomFractals/vscode-leaflet/main/data/geojson/world-countries.geojson","outputs":[]},{"kind":2,"language":"rest-book","value":"GET https://raw.githubusercontent.com/RandomFractals/vscode-leaflet/main/data/csv/world-countries.csv","outputs":[]}] -------------------------------------------------------------------------------- /notebooks/world-gdp.restbook: -------------------------------------------------------------------------------- 1 | [{"kind":1,"language":"markdown","value":"# World GDP REST Book 📓\r\n\r\nData source: [https://www.kaggle.com/tunguz/country-regional-and-world-gdp](https://www.kaggle.com/tunguz/country-regional-and-world-gdp)","outputs":[]},{"kind":2,"language":"rest-book","value":"GET https://raw.githubusercontent.com/RandomFractals/vscode-data-table/main/data/world-gdp.csv","outputs":[]}] -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "unfolded-map-renderer", 3 | "displayName": "Unfolded Map Renderer", 4 | "description": "Unfolded Map 🗺️ Renderer for Notebook 📓 cell ⌗ data outputs", 5 | "version": "1.0.0", 6 | "engines": { 7 | "vscode": "^1.62.0" 8 | }, 9 | "icon": "resources/icons/unfolded.jfif", 10 | "publisher": "RandomFractalsInc", 11 | "author": "Taras Novak", 12 | "contributors": [ 13 | "Taras Novak" 14 | ], 15 | "license": "Apache-2.0", 16 | "readme": "README.md", 17 | "repository": { 18 | "type": "git", 19 | "url": "https://github.com/RandomFractals/unfolded-map-renderer" 20 | }, 21 | "bugs": "https://github.com/RandomFractals/unfolded-map-renderer/issues", 22 | "homepage": "https://github.com/RandomFractals/unfolded-map-renderer/README.md", 23 | "galleryBanner": { 24 | "color": "#333", 25 | "theme": "dark" 26 | }, 27 | "categories": [ 28 | "Data Science", 29 | "Formatters", 30 | "Education", 31 | "Machine Learning", 32 | "Notebooks", 33 | "Visualization" 34 | ], 35 | "keywords": [ 36 | "unfolded", 37 | "map", 38 | "GeoJSON", 39 | "JSON", 40 | "CSV", 41 | "XML", 42 | "flat data", 43 | "geo location", 44 | "text", 45 | "view", 46 | ".NET Interactive", 47 | "REST Book", 48 | "TypeScript", 49 | "Pyolite", 50 | "notebook", 51 | "cell", 52 | "output", 53 | "renderer" 54 | ], 55 | "activationEvents": [], 56 | "main": "./out/extension/extension.js", 57 | "contributes": { 58 | "notebookRenderer": [ 59 | { 60 | "id": "unfolded-map", 61 | "entrypoint": "./out/renderer/index.js", 62 | "displayName": "Unfolded Map", 63 | "mimeTypes": [ 64 | "application/geo+json", 65 | "application/topo+json", 66 | "application/json", 67 | "application/vnd.code.notebook.stdout", 68 | "application/xml", 69 | "text/csv", 70 | "text/plain", 71 | "text/xml" 72 | ] 73 | } 74 | ] 75 | }, 76 | "scripts": { 77 | "vscode:prepublish": "npm run compile && node out/test/checkNoTestProvider.js", 78 | "compile": "npm run compile:extension && npm run compile:renderer", 79 | "compile:extension": "tsc -b", 80 | "compile:renderer": "webpack --mode production", 81 | "lint": "eslint src --ext ts", 82 | "watch": "concurrently -r \"npm:watch:*\"", 83 | "watch:extension": "tsc -b --watch", 84 | "watch:renderer": "webpack --mode development --watch", 85 | "dev": "concurrently -r npm:watch:extension npm:renderer", 86 | "pretest": "npm run compile && npm run lint", 87 | "test": "node ./out/test/runTest.js" 88 | }, 89 | "devDependencies": { 90 | "@types/d3-dsv": "^3.0.0", 91 | "@types/glob": "^7.2.0", 92 | "@types/mocha": "^9.0.0", 93 | "@types/node": "^16.11.7", 94 | "@types/vscode": "^1.62.0", 95 | "@types/vscode-notebook-renderer": "^1.60.0", 96 | "@types/webpack-env": "^1.16.3", 97 | "@typescript-eslint/eslint-plugin": "^5.3.1", 98 | "@typescript-eslint/parser": "^5.3.1", 99 | "concurrently": "^6.4.0", 100 | "css-loader": "^6.5.1", 101 | "eslint": "^8.2.0", 102 | "glob": "^7.2.0", 103 | "mocha": "^9.1.3", 104 | "style-loader": "^3.3.1", 105 | "svg-inline-loader": "^0.8.2", 106 | "ts-loader": "^9.2.6", 107 | "typescript": "^4.4.4", 108 | "vscode-notebook-error-overlay": "^1.0.1", 109 | "vscode-test": "^1.6.1", 110 | "webpack": "^5.64.0", 111 | "webpack-cli": "^4.9.1" 112 | }, 113 | "dependencies": { 114 | "d3-dsv": "^3.0.1", 115 | "htl": "^0.3.1", 116 | "fast-xml-parser": "^3.21.1", 117 | "@unfolded/map-sdk": "0.3.1" 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /resources/icons/map.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RandomFractals/unfolded-map-renderer/f4b457d19ad1e2e017adece1649f5eb274a17326/resources/icons/map.png -------------------------------------------------------------------------------- /resources/icons/map.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 7 | 8 | 10 | 12 | 14 | 15 | -------------------------------------------------------------------------------- /resources/icons/unfolded.jfif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RandomFractals/unfolded-map-renderer/f4b457d19ad1e2e017adece1649f5eb274a17326/resources/icons/unfolded.jfif -------------------------------------------------------------------------------- /src/extension/extension.ts: -------------------------------------------------------------------------------- 1 | import {ExtensionContext} from 'vscode'; 2 | 3 | export function activate(context: ExtensionContext) { 4 | console.log(`unfolded.map: activated`); 5 | } 6 | 7 | export function deactivate() { 8 | console.log(`unfolded.map: deactivated`); 9 | } 10 | -------------------------------------------------------------------------------- /src/extension/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig-base.json", 3 | "compilerOptions": { 4 | "rootDir": ".", 5 | "outDir": "../../out/extension", 6 | }, 7 | "references": [] 8 | } 9 | -------------------------------------------------------------------------------- /src/renderer/config.ts: -------------------------------------------------------------------------------- 1 | 2 | // rendered map hight 3 | export const mapHeight = 480; 4 | 5 | // map config template 6 | export const mapConfigTemplate: any = { 7 | "config": { 8 | "mapState": { 9 | "bearing": 0, 10 | "dragRotate": false, 11 | "isSplit": false, 12 | "latitude": 10.5117765, 13 | "longitude": 34.269600000000004, 14 | "pitch": 0, 15 | "zoom": 2 16 | }, 17 | "mapStyle": { 18 | "mapStyles": {}, 19 | "styleType": "muted_night", 20 | "threeDBuildingColor": [ 21 | 9.665468314072013, 22 | 17.18305478057247, 23 | 31.1442867897876 24 | ], 25 | "topLayerGroups": {}, 26 | "visibleLayerGroups": { 27 | "border": true, 28 | "building": true, 29 | "label": true, 30 | "land": true, 31 | "road": true, 32 | "water": true 33 | } 34 | }, 35 | "visState": { 36 | "animationConfig": { 37 | "currentTime": null, 38 | "speed": 1 39 | }, 40 | "filters": [], 41 | "interactionConfig": { 42 | "brush": { 43 | "enabled": false, 44 | "size": 0.5 45 | }, 46 | "coordinate": { 47 | "enabled": false 48 | }, 49 | "tooltip": { 50 | "enabled": true, 51 | "fieldsToShow": {} 52 | } 53 | }, 54 | "layerBlending": "normal", 55 | "layers": [], 56 | "splitMaps": [] 57 | } 58 | }, 59 | "version": "v1" 60 | }; 61 | 62 | export const mapboxToken: string = 'pk.eyJ1IjoiZGF0YXBpeHkiLCJhIjoiY2s1Mm10bHB1MThnbDNrdGVmemptd3J5eSJ9.xewq9dOWQLemerED1-qPXQ'; 63 | 64 | /** 65 | * Creates default map styles for the map. 66 | * @param {*} mapboxToken Mapbox token to use. 67 | * @returns 68 | */ 69 | export function createMapStyles(mapboxToken: string) { 70 | const defaultLayerGroups: [] = []; 71 | return [ 72 | { 73 | id: 'dark_streets', 74 | label: 'Dark Streets', 75 | url: 'mapbox://styles/mapbox/dark-v10', 76 | icon: `https://api.mapbox.com/styles/v1/mapbox/dark-v10/static/-87.623177,41.881832,9.19,0,0/400x300?access_token=${mapboxToken}&logo=false&attribution=false`, 77 | layerGroups: defaultLayerGroups 78 | }, 79 | { 80 | id: 'light_streets', 81 | label: 'Light Streets', 82 | url: 'mapbox://styles/mapbox/light-v10', 83 | icon: `https://api.mapbox.com/styles/v1/mapbox/light-v10/static/-87.623177,41.881832,9.19,0,0/400x300?access_token=${mapboxToken}&logo=false&attribution=false`, 84 | layerGroups: defaultLayerGroups 85 | }, 86 | /* { // note: looks same as outdoors 87 | id: 'streets', 88 | label: 'Streets', 89 | url: 'mapbox://styles/mapbox/streets-v10', 90 | icon: `https://api.mapbox.com/styles/v1/mapbox/streets-v10/static/-87.623177,41.881832,9.19,0,0/400x300?access_token=${mapboxToken}&logo=false&attribution=false`, 91 | layerGroups: defaultLayerGroups 92 | }, */ 93 | { 94 | id: 'outdoors', 95 | label: 'Outdoors', 96 | url: 'mapbox://styles/mapbox/outdoors-v10', 97 | icon: `https://api.mapbox.com/styles/v1/mapbox/outdoors-v10/static/-87.623177,41.881832,9.19,0,0/400x300?access_token=${mapboxToken}&logo=false&attribution=false`, 98 | layerGroups: defaultLayerGroups 99 | }, 100 | { 101 | id: 'satellite', 102 | label: 'Satellite', 103 | url: 'mapbox://styles/mapbox/satellite-v9', 104 | icon: `https://api.mapbox.com/styles/v1/mapbox/satellite-v9/static/-87.623177,41.881832,9.19,0,0/400x300?access_token=${mapboxToken}&logo=false&attribution=false`, 105 | layerGroups: defaultLayerGroups 106 | } 107 | ]; 108 | } 109 | -------------------------------------------------------------------------------- /src/renderer/css.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.css' { 2 | const classes: { [className: string]: string }; 3 | export = classes; 4 | } 5 | -------------------------------------------------------------------------------- /src/renderer/geoConverter.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/naming-convention */ 2 | /** 3 | * Loosely based on https://github.com/eugeneYWang/GeoJSON.ts 4 | */ 5 | export class GeoConverter { 6 | 7 | // supported geometry object types 8 | // see GeoJSON spec: https://www.rfc-editor.org/rfc/rfc7946.html#section-1.4 9 | private geometryTypes = [ 10 | 'Point', 11 | 'MultiPoint', 12 | 'LineString', 13 | 'MultiLineString', 14 | 'Polygon', 15 | 'MultiPolygon', 16 | 'GeoJSON' 17 | ]; 18 | 19 | // geometry object properties 20 | private geometryProperties: Array = []; 21 | 22 | // default geo data conversion options 23 | defaultOptions: object = { 24 | doThrows: { 25 | invalidGeometry: false 26 | } 27 | }; 28 | 29 | /** 30 | * Geo data conversion errors. 31 | */ 32 | errors: object = { 33 | invalidGeometryError: this.invalidGeometryError 34 | }; 35 | 36 | /** 37 | * Creates new Geo data converter instance. 38 | */ 39 | constructor() { 40 | } 41 | 42 | /** 43 | * Converts array or data object to GeoJSON object. 44 | * @param objects Data objects to convert. 45 | * @param options Geo data conversion options. 46 | * @param callback Optional callback for data conversion. 47 | * @returns GeoJSON data object. 48 | */ 49 | public toGeo(objects: [] | object, options: object, callback?: Function): any { 50 | let geoJson: any; 51 | 52 | // apply geo data conversion default settings 53 | let settings = this.applyDefaults(options, this.defaultOptions); 54 | 55 | // reset geometry fields 56 | this.geometryProperties.length = 0; 57 | this.setGeometry(settings); 58 | if (Array.isArray(objects)) { 59 | // create geo features collection 60 | geoJson = {type: 'FeatureCollection', features: []}; 61 | objects.forEach(item => { 62 | const feature: any = this.getFeature(item, settings); 63 | if (feature.geometry?.type !== undefined) { // has geometry type and coordinates 64 | geoJson.features.push(feature); 65 | } 66 | }); 67 | this.addOptionalProperties(geoJson, settings); 68 | } 69 | else { 70 | // create geo data object from a single data object 71 | geoJson = this.getFeature(objects, settings); 72 | this.addOptionalProperties(geoJson, settings); 73 | } 74 | 75 | if (callback && typeof callback === 'function') { 76 | callback(geoJson); 77 | } 78 | else { 79 | return geoJson; 80 | } 81 | } 82 | 83 | /** 84 | * Adds default settings to geo data parameters. 85 | * Does not overwrite any data properties. 86 | * Only adds additional defaults. 87 | * @param params Geo data parameters. 88 | * @param defaults Default settings. 89 | * @returns 90 | */ 91 | private applyDefaults(params: any, defaults: any): any { 92 | let settings: any = params || {}; 93 | for (let setting in settings) { 94 | if (defaults.hasOwnProperty(setting) && !settings[setting]) { 95 | // add default setting 96 | settings[setting] = defaults[setting]; 97 | } 98 | } 99 | return settings; 100 | } 101 | 102 | /** 103 | * Adds optional crs and bbox GeoJSON properties, if present. 104 | * @param geoJson Geo data object to update. 105 | * @param settings Geo data setttings. 106 | */ 107 | private addOptionalProperties(geoJson: any, settings: any) { 108 | if (settings.crs && this.isValidCrs(settings.crs)) { 109 | if (settings.isPostgres) { 110 | geoJson.geometry.crs = settings.crs; 111 | } else { 112 | geoJson.crs = settings.crs; 113 | } 114 | } 115 | if (settings.bbox) { 116 | geoJson.bbox = settings.bbox; 117 | } 118 | if (settings.extraGlobal) { 119 | geoJson.properties = {}; 120 | for (let key in settings.extraGlobal) { 121 | geoJson.properties[key] = settings.extraGlobal[key]; 122 | } 123 | } 124 | } 125 | 126 | /** 127 | * Validates geo data CRS config structure. 128 | * @param crs Crs to validate. 129 | * @returns 130 | */ 131 | private isValidCrs(crs: any): boolean { 132 | if (crs.type === 'name') { 133 | if (crs.properties && crs.properties.name) { 134 | return true; 135 | } 136 | else { 137 | throw new Error('Invalid CRS. Properties must contain "name" key.'); 138 | } 139 | } 140 | else if (crs.type === 'link') { 141 | if (crs.properties && crs.properties.href && crs.properties.type) { 142 | return true; 143 | } 144 | else { 145 | throw new Error('Invalid CRS. Properties must contain "href" and "type" key.'); 146 | } 147 | } 148 | else { 149 | throw new Error('Invald CRS. Type attribute must be "name" or "link".'); 150 | } 151 | } 152 | 153 | /** 154 | * Moves geometry settings to the `geometry` key for easier access. 155 | * @param settings Geometry data settings. 156 | */ 157 | private setGeometry(settings: any): void { 158 | settings.geometry = {}; 159 | for (let propertyName in settings) { 160 | if (settings.hasOwnProperty(propertyName) && 161 | this.geometryTypes.indexOf(propertyName) >= 0) { 162 | settings.geometry[propertyName] = settings[propertyName]; 163 | delete settings[propertyName]; 164 | } 165 | } 166 | this.setGeometryProperties(settings.geometry); 167 | } 168 | 169 | /** 170 | * Adds fields with geometry data to geometry object properties. 171 | * Geometry properties are used when adding properties to geo features, 172 | * so that no geometry fields are added to the geo properties collection. 173 | * @param geoSettings Geometry data settings. 174 | */ 175 | private setGeometryProperties(geoSettings: any): void { 176 | for (let propertyName in geoSettings) { 177 | if (geoSettings.hasOwnProperty(propertyName)) { 178 | if (typeof geoSettings[propertyName] === 'string') { 179 | this.geometryProperties.push(geoSettings[propertyName]); 180 | } 181 | else if (typeof geoSettings[propertyName] === 'object') { 182 | // array of coordinates for Point object 183 | this.geometryProperties.push(geoSettings[propertyName][0]); 184 | this.geometryProperties.push(geoSettings[propertyName][1]); 185 | } 186 | } 187 | } 188 | 189 | if (this.geometryProperties.length === 0) { 190 | throw new Error("No geometry attributes specified."); 191 | } 192 | } 193 | 194 | /** 195 | * Creates a Feature object for the GeoJSON features collection. 196 | * @param item Data item object. 197 | * @param settings Geo data conversion settings. 198 | * @returns Feature object with geometry and data properties. 199 | */ 200 | private getFeature(item: any, settings: any): object { 201 | let feature: any = {type: 'Feature'}; 202 | feature['geometry'] = this.buildGeometry(item, settings); 203 | feature['properties'] = this.getDataProperties(item, settings); 204 | return feature; 205 | } 206 | 207 | /** 208 | * Creates data properties collection for the GeoJSON Feature object. 209 | * @param item Data item object. 210 | * @param settings Geo data conversion settings. 211 | * @returns Feature object with geometry and data properties. 212 | */ 213 | private getDataProperties(item: any, settings: any): object { 214 | let data: any = {}; 215 | // TODO: add include and extra data props support 216 | // from: https://github.com/eugeneYWang/GeoJSON.ts/blob/master/geojson.ts#L343 217 | for (let propertyName in item) { 218 | if (item.hasOwnProperty(propertyName) && 219 | this.geometryProperties.indexOf(propertyName) === -1 && 220 | settings.exclude.indexOf(propertyName) === -1) { 221 | // add it to geometry feature data properties 222 | data[propertyName] = item[propertyName]; 223 | } 224 | } 225 | return data; 226 | } 227 | 228 | /** 229 | * Checks for nested objects. 230 | * @param value Object value. 231 | * @returns 232 | */ 233 | private isNested(value: any) { 234 | return /^.+\..+$/.test(value); 235 | } 236 | 237 | /** 238 | * Creates geometry object for the geo data feature. 239 | * @param item Data item. 240 | * @param settings Geo data settings. 241 | * @returns Geometry data object. 242 | */ 243 | private buildGeometry(item: any, settings: any): any { 244 | let geometry: any = {}; 245 | for (let geometryType in settings.geometry) { 246 | let geometryProperty = settings.geometry[geometryType]; 247 | if (typeof geometryProperty === 'string' && item.hasOwnProperty(geometryProperty)) { 248 | // string point: {Point: 'coords'} 249 | if (geometryType === 'GeoJSON') { 250 | geometry = item[geometryProperty]; 251 | } 252 | else { 253 | geometry['type'] = geometryType; 254 | geometry['coordinates'] = item[geometryProperty]; 255 | } 256 | } 257 | else if (typeof geometryProperty === 'object' && !Array.isArray(geometryProperty)) { 258 | /* polygons of form 259 | Polygon: { 260 | northeast: ['lat', 'lng'], 261 | southwest: ['lat', 'lng'] 262 | } 263 | */ 264 | let points: any = Object.keys(geometryProperty).map((key: string) => { 265 | let order = geometryProperty[key]; 266 | let newItem = item[key]; 267 | return this.buildGeometry(newItem, {geometry: {Point: order}}); 268 | }); 269 | geometry['type'] = geometryType; 270 | geometry['coordinates'] = [].concat( 271 | points.map((point: any) => point.coordinates) 272 | ); 273 | } 274 | else if (Array.isArray(geometryProperty) && 275 | item.hasOwnProperty(geometryProperty[0]) && 276 | item.hasOwnProperty(geometryProperty[1]) && 277 | item.hasOwnProperty(geometryProperty[2])) { 278 | // point coordinates with alt: {Point: ['lat', 'lng', 'alt']} 279 | geometry['type'] = geometryType; 280 | geometry['coordinates'] = [ 281 | Number(item[geometryProperty[1]]), 282 | Number(item[geometryProperty[0]]), 283 | Number(item[geometryProperty[2]]) 284 | ]; 285 | } 286 | else if (Array.isArray(geometryProperty) && 287 | item.hasOwnProperty(geometryProperty[0]) && 288 | item.hasOwnProperty(geometryProperty[1])) { 289 | // point coordinates: {Point: ['lat', 'lng']} 290 | geometry['type'] = geometryType; 291 | geometry['coordinates'] = [Number(item[geometryProperty[1]]), Number(item[geometryProperty[0]])]; 292 | } 293 | else if (Array.isArray(geometryProperty) && 294 | this.isNested(geometryProperty[0]) && 295 | this.isNested(geometryProperty[1]) && 296 | this.isNested(geometryProperty[2])) { 297 | // nested point coordinates with alt: {Point: ['container.lat', 'container.lng', 'container.alt']} 298 | let coordinates = []; 299 | for (let i = 0; i < geometryProperty.length; i++) { 300 | // i.e. 0 and 1 301 | var paths = geometryProperty[i].split('.'); 302 | var itemClone = item; 303 | for (var j = 0; j < paths.length; j++) { 304 | if (!itemClone.hasOwnProperty(paths[j])) { 305 | return false; 306 | } 307 | // iterate deeper into the object 308 | itemClone = itemClone[paths[j]]; 309 | } 310 | coordinates[i] = itemClone; 311 | } 312 | geometry['type'] = geometryType; 313 | geometry['coordinates'] = [ 314 | Number(coordinates[1]), 315 | Number(coordinates[0]), 316 | Number(coordinates[2]) 317 | ]; 318 | } 319 | else if (Array.isArray(geometryProperty) && 320 | this.isNested(geometryProperty[0]) && 321 | this.isNested(geometryProperty[1])) { 322 | // nested point coordinates: {Point: ['container.lat', 'container.lng']} 323 | let coordinates = []; 324 | for (let i = 0; i < geometryProperty.length; i++) { 325 | // i.e. 0 and 1 326 | let paths = geometryProperty[i].split("."); 327 | let itemClone = item; 328 | for (let j = 0; j < paths.length; j++) { 329 | if (!itemClone.hasOwnProperty(paths[j])) { 330 | return false; 331 | } 332 | // iterate deeper into the object 333 | itemClone = itemClone[paths[j]]; 334 | } 335 | coordinates[i] = itemClone; 336 | } 337 | geometry['type'] = geometryType; 338 | geometry['coordinates'] = [Number(coordinates[1]), Number(coordinates[0])]; 339 | } 340 | else if (Array.isArray(geometryProperty) && 341 | geometryProperty[0].constructor.name === 'Object' && 342 | Object.keys(geometryProperty[0])[0] === 'coordinates') { 343 | // coordinates point: {Point: [{coordinates: [lat, lng]}]} 344 | geometry['type'] = geometryType; 345 | geometry['coordinates'] = [ 346 | Number(item.coordinates[geometryProperty[0].coordinates.indexOf('lng')]), 347 | Number(item.coordinates[geometryProperty[0].coordinates.indexOf('lat')]) 348 | ]; 349 | } 350 | } 351 | 352 | if (settings.doThrows && 353 | settings.doThrows.invalidGeometry && 354 | !this.isValidGeometry(geometry)) { 355 | throw this.invalidGeometryError(item, settings); 356 | } 357 | 358 | return geometry; 359 | } 360 | 361 | 362 | /** 363 | * Generates invalid geometry error. 364 | * @param args Geometry data arguments. 365 | */ 366 | invalidGeometryError(...args: any[]): Error { 367 | let errorArgs = (1 <= args.length) ? [].slice.call(args, 0) : []; 368 | let item = errorArgs.shift(); 369 | let params = errorArgs.shift(); 370 | throw Error(`Invalid Geometry: item: ${JSON.stringify(item, null, 2)} 371 | \n params: ${JSON.stringify(params, null, 2)}`); 372 | } 373 | 374 | /** 375 | * Validates geometry object. 376 | * @param geometry Geometry object to validate. 377 | * @returns 378 | */ 379 | isValidGeometry(geometry: any): boolean { 380 | if (!geometry || !Object.keys(geometry).length) { 381 | return false; 382 | } 383 | return true; 384 | }; 385 | 386 | /** 387 | * Adds data contained in the `extra` parameter to geo data properties. 388 | * @param properties Geo data properties to update. 389 | * @param extra Extra properties to add. 390 | * @returns Updated geo data properties. 391 | */ 392 | private addExtraProperties(properties: any, extra: any) { 393 | for (var key in extra) { 394 | if (extra.hasOwnProperty(key)) { 395 | properties[key] = extra[key]; 396 | } 397 | } 398 | return properties; 399 | } 400 | } 401 | -------------------------------------------------------------------------------- /src/renderer/index.ts: -------------------------------------------------------------------------------- 1 | import type { 2 | ActivationFunction, 3 | OutputItem 4 | } from 'vscode-notebook-renderer'; 5 | import errorOverlay from 'vscode-notebook-error-overlay'; 6 | import {render} from './renderer'; 7 | 8 | export const activate: ActivationFunction = context => { 9 | return { 10 | renderOutputItem(outputItem: OutputItem, element: HTMLElement) { 11 | errorOverlay.wrap(element, () => { 12 | const cellOutputContainer: HTMLDivElement = document.createElement('div'); 13 | cellOutputContainer.className = 'unfolded-map'; 14 | element.appendChild(cellOutputContainer); 15 | render({ 16 | container: cellOutputContainer, 17 | mimeType: outputItem.mime, 18 | value: outputItem, 19 | context 20 | }); 21 | }); 22 | }, 23 | disposeOutputItem(outputId: string) { 24 | // Note: outputId is the cell output being cleared, 25 | // or undefined if we're clearing all outputs. 26 | } 27 | }; 28 | }; 29 | -------------------------------------------------------------------------------- /src/renderer/outputLoader.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/naming-convention */ 2 | import type {OutputItem} from 'vscode-notebook-renderer'; 3 | import {GeoConverter} from './geoConverter'; 4 | import {csvParse} from 'd3-dsv'; 5 | const xmlParser = require('fast-xml-parser'); 6 | 7 | /** 8 | * OutputLoader loads data from notebook cell output item. 9 | */ 10 | export class OutputLoader { 11 | 12 | private geoConverter: GeoConverter; 13 | 14 | /** 15 | * Creates new OutputLoader instance. 16 | * @param outputData Notebook cell output item. 17 | * @param mimeType Notebook cell output mime type. 18 | */ 19 | constructor (private outputData: OutputItem, private mimeType: string) { 20 | this.geoConverter = new GeoConverter(); 21 | } 22 | 23 | /** 24 | * Gets data output. 25 | */ 26 | getData(): any { 27 | // try getting JSON data first 28 | const objectData = this.getJsonData(this.outputData); 29 | if (objectData !== undefined) { 30 | if (objectData.features) { 31 | // console.log('unfolded.map:data:format: GeoJSON'); 32 | // already in geoJSON data format for map display 33 | return objectData; 34 | } 35 | else { 36 | // try to convert it to GeoJSON data format for map display 37 | return this.getGeoData(objectData); 38 | } 39 | } 40 | 41 | // try parsing text data 42 | let textData: string = this.outputData.text(); 43 | if (textData.length > 0) { 44 | console.log('unfolded.map:data:text:', textData.substring(0, Math.min(80, textData.length)), '...'); 45 | 46 | // load JSON data 47 | const jsonData = this.getJsonData(textData); 48 | let outputData: any; 49 | if (jsonData !== undefined) { 50 | outputData = jsonData; 51 | } 52 | else if (textData.startsWith(' 0 ) { 76 | console.log(`unfolded.map:dataType: ${dataArray.constructor}`); 77 | // return aq.fromArrow(dataArray); 78 | } 79 | 80 | return this.outputData; 81 | } 82 | 83 | /** 84 | * Gets JSON object or data array, 85 | * CSV rows data array, or undefined 86 | * for plain text and binary data types. 87 | * @param data Notebook cell output data value. 88 | */ 89 | getJsonData(data: any): any { 90 | // console.log('unfolded.map:data:json:', data); 91 | try { 92 | if (typeof data === 'string') { 93 | // try parsing JSON string 94 | const textData: string = this.patchJson(data); 95 | const objectData: any = JSON.parse(textData); 96 | if (Array.isArray(objectData)) { 97 | console.log('unfolded.map:data:format: JSON array'); 98 | return objectData; 99 | } 100 | else { 101 | console.log('unfolded.map:data:format: JSON'); 102 | return objectData; 103 | } 104 | } 105 | 106 | // try getting json data object 107 | // console.log('unfolded.map:data:json:', data); 108 | let jsonData: any = data.json(); 109 | if (jsonData.data) { 110 | // use data object from REST response 111 | jsonData = jsonData.data; 112 | } 113 | 114 | if (jsonData.features) { 115 | console.log('unfolded.map:data:format: GeoJSON'); 116 | return jsonData; 117 | } 118 | 119 | if (Array.isArray(jsonData)) { 120 | console.log('unfolded.map:data:format: JSON array'); 121 | return jsonData; 122 | } 123 | 124 | if (typeof jsonData === 'string') { 125 | if (this.isCsv(jsonData)) { 126 | // parse CSV data for JSON response from REST Book 127 | // see: https://github.com/tanhakabir/rest-book/issues/114 128 | return csvParse(jsonData); 129 | } 130 | else if (jsonData.startsWith(' 0) { 182 | console.log('unfolded.map:data:lines:', lines); 183 | const columns: string[] = lines[0].split(','); 184 | const columnCount = columns.length; 185 | 186 | if (columnCount > 1) { 187 | console.log('unfolded.map:data:columns:', columns); 188 | // check columns for garbled json 189 | for (let k =0; k < columnCount; k++) { 190 | let columnName: string = columns[k]; 191 | if (columnName.startsWith('[') || columnName.startsWith('{')) { 192 | return false; 193 | } 194 | } 195 | 196 | // do naive check for some commas in the first 9 rows 197 | for (let i = 1; i < minRows; i++) { 198 | const columnValues: string[] = lines[i].split(','); 199 | // console.log(`data.table:row[${i}]`, columnValues); 200 | if (columnValues.length < columnCount) { 201 | return false; 202 | } 203 | } 204 | console.log('unfolded.map:data:format: CSV'); 205 | return true; 206 | } 207 | } 208 | return false; 209 | } 210 | 211 | /** 212 | * Parses xml data. 213 | * @param xml Xml data string. 214 | */ 215 | xmlParse(xml: string): any { 216 | let jsonData = {}; 217 | const xmlParserOptions = { 218 | attributeNamePrefix : '', 219 | textNodeName : 'value', 220 | ignoreAttributes : false, 221 | ignoreNameSpace : true, 222 | allowBooleanAttributes : true, 223 | parseNodeValue : true, 224 | parseAttributeValue : true, 225 | trimValues: true, 226 | // parseTrueNumberOnly: false, 227 | // arrayMode: false, //"strict" 228 | }; 229 | try { 230 | jsonData = xmlParser.parse(xml, xmlParserOptions); // , true); // validate xml 231 | console.log('unfolded.map:data:format: XML'); 232 | // console.log(JSON.stringify(jsonData, null, 2)); 233 | } 234 | catch(error: any) { 235 | console.log('unfolded.map:data: XML parse error:\n', error.message); 236 | } 237 | return jsonData; 238 | } 239 | 240 | /** 241 | * Gets geo data in GeoJSON format. 242 | * @param data Data object. 243 | */ 244 | getGeoData(data: any): any { 245 | let geoData = data; 246 | try { 247 | geoData = this.geoConverter.toGeo(data, this.getGeoDataOptions(data)); 248 | } 249 | catch(error: any) { 250 | console.log('unfolded.map:data: GeoJSON parse error:\n', error); 251 | } 252 | if (!geoData.features || geoData.features.length <= 0) { 253 | // console.log(`unfolded.map:data:features: ${JSON.stringify(geoData.features, null, 2)}`); 254 | // use parsed data input instead 255 | return data; 256 | } 257 | return geoData; 258 | } 259 | 260 | /** 261 | * Gets geo data conversion options. 262 | * @param data Data to inspect. 263 | * @returns Geo converter options. 264 | */ 265 | getGeoDataOptions(data: any): any { 266 | const geoOptions = { 267 | Point: ['latitude', 'longitude'], 268 | removeInvalidGeometries: true, 269 | exclude: [ 270 | 'geometry.bbox', 271 | 'geometry.type', 272 | 'geometry.coordinates' 273 | ] 274 | }; 275 | 276 | // get data object to inspect 277 | let dataItem: any = data; 278 | if (Array.isArray(data) && data.length > 0) { 279 | dataItem = data[0]; 280 | } 281 | 282 | // inspect flat data object 283 | let latitudePropertyName, longitudePropertyName; 284 | for (let propertyName in dataItem) { 285 | if (dataItem.hasOwnProperty(propertyName)) { 286 | const geoPropertyName: string = propertyName.toLowerCase(); 287 | // check for latitude/longitude, lat/lng, lat/lon point pairs 288 | if (geoPropertyName.endsWith('latitude')) { 289 | latitudePropertyName = propertyName; 290 | } 291 | else if (geoPropertyName.endsWith('lat')) { 292 | latitudePropertyName = propertyName; 293 | } 294 | else if (geoPropertyName.endsWith('longitude')) { 295 | longitudePropertyName = propertyName; 296 | } 297 | else if (geoPropertyName.endsWith('lon')) { 298 | longitudePropertyName = propertyName; 299 | } 300 | else if (geoPropertyName.endsWith('lng')) { 301 | longitudePropertyName = propertyName; 302 | } 303 | } 304 | } 305 | 306 | if (latitudePropertyName && longitudePropertyName) { 307 | // add point data fields 308 | geoOptions.Point = [latitudePropertyName, longitudePropertyName]; 309 | } 310 | return geoOptions; 311 | } 312 | } 313 | -------------------------------------------------------------------------------- /src/renderer/renderer.ts: -------------------------------------------------------------------------------- 1 | import type { 2 | RendererContext, 3 | OutputItem 4 | } from 'vscode-notebook-renderer'; 5 | 6 | import {OutputLoader} from './outputLoader'; 7 | 8 | // import renderer and map styles 9 | import './styles/styles.css'; 10 | import './styles/mapbox-gl.css'; 11 | import './styles/uber-fonts.css'; 12 | 13 | // import map helper 14 | const unfoldedMap = require('./unfoldedMap.js'); 15 | 16 | /** 17 | * Notebook cell output render info. 18 | */ 19 | interface IRenderInfo { 20 | container: HTMLElement; 21 | mimeType: string; 22 | value: OutputItem; 23 | context: RendererContext; 24 | } 25 | 26 | /** 27 | * Renders notebook cell output. 28 | * @param output Notebook cell output info to render. 29 | */ 30 | export function render(output: IRenderInfo) { 31 | console.log(`unfolded.map:data:mimeType: ${output.mimeType}`); 32 | const outputLoader: OutputLoader = new OutputLoader(output.value, output.mimeType); 33 | let data: any = outputLoader.getData(); 34 | if (data.features && data.features.length > 0) { // has geometry features to display 35 | // create unfolded map and add it to notebook cell output display 36 | let mapContainer: HTMLDivElement = document.createElement('div'); 37 | mapContainer.className = 'map-container'; 38 | mapContainer = output.container.appendChild(mapContainer); 39 | try { 40 | // try to load geo data on the map 41 | const map = unfoldedMap.createMap(data, mapContainer); 42 | } 43 | catch(error: any) { 44 | console.error('unfolded.map:data: GeoJSON parse error:\n', error); 45 | showTextData(data, output); 46 | } 47 | } 48 | else { 49 | showTextData(data, output); 50 | } 51 | } 52 | 53 | if (module.hot) { 54 | module.hot.addDisposeHandler(() => { 55 | // cleanup or stash any state on renderer dispose 56 | }); 57 | } 58 | 59 | /** 60 | * Displays text data. 61 | */ 62 | function showTextData(data: any, output: IRenderInfo): void { 63 | // create text output display nodes 64 | const pre = document.createElement('pre'); 65 | pre.className = 'text-output'; 66 | const code = document.createElement('code'); 67 | if (typeof data !== 'string') { 68 | // stringify json data 69 | code.textContent = JSON.stringify(data, null, 2); 70 | } 71 | else { 72 | // show cell output text 73 | code.textContent = output.value.text(); 74 | } 75 | pre.appendChild(code); 76 | output.container.appendChild(pre); 77 | } 78 | -------------------------------------------------------------------------------- /src/renderer/styles/mapbox-gl.css: -------------------------------------------------------------------------------- 1 | /* styles from: https://api.tiles.mapbox.com/mapbox-gl-js/v1.1.1/mapbox-gl.css */ 2 | .mapboxgl-map { 3 | font: 12px/20px 'Helvetica Neue', Arial, Helvetica, sans-serif; 4 | overflow: hidden; 5 | position: relative; 6 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0); 7 | text-align: left; 8 | } 9 | 10 | .mapboxgl-map:-webkit-full-screen { 11 | width: 100%; 12 | height: 100%; 13 | } 14 | 15 | .mapboxgl-canary { 16 | background-color: salmon; 17 | } 18 | 19 | .mapboxgl-canvas-container.mapboxgl-interactive, 20 | .mapboxgl-ctrl-group > button.mapboxgl-ctrl-compass { 21 | cursor: -webkit-grab; 22 | cursor: -moz-grab; 23 | cursor: grab; 24 | -moz-user-select: none; 25 | -webkit-user-select: none; 26 | -ms-user-select: none; 27 | user-select: none; 28 | } 29 | 30 | .mapboxgl-canvas-container.mapboxgl-interactive.mapboxgl-track-pointer { 31 | cursor: pointer; 32 | } 33 | 34 | .mapboxgl-canvas-container.mapboxgl-interactive:active, 35 | .mapboxgl-ctrl-group > button.mapboxgl-ctrl-compass:active { 36 | cursor: -webkit-grabbing; 37 | cursor: -moz-grabbing; 38 | cursor: grabbing; 39 | } 40 | 41 | .mapboxgl-canvas-container.mapboxgl-touch-zoom-rotate, 42 | .mapboxgl-canvas-container.mapboxgl-touch-zoom-rotate .mapboxgl-canvas { 43 | touch-action: pan-x pan-y; 44 | } 45 | 46 | .mapboxgl-canvas-container.mapboxgl-touch-drag-pan, 47 | .mapboxgl-canvas-container.mapboxgl-touch-drag-pan .mapboxgl-canvas { 48 | touch-action: pinch-zoom; 49 | } 50 | 51 | .mapboxgl-canvas-container.mapboxgl-touch-zoom-rotate.mapboxgl-touch-drag-pan, 52 | .mapboxgl-canvas-container.mapboxgl-touch-zoom-rotate.mapboxgl-touch-drag-pan .mapboxgl-canvas { 53 | touch-action: none; 54 | } 55 | 56 | .mapboxgl-ctrl-top-left, 57 | .mapboxgl-ctrl-top-right, 58 | .mapboxgl-ctrl-bottom-left, 59 | .mapboxgl-ctrl-bottom-right { position: absolute; pointer-events: none; z-index: 2; } 60 | .mapboxgl-ctrl-top-left { top: 0; left: 0; } 61 | .mapboxgl-ctrl-top-right { top: 0; right: 0; } 62 | .mapboxgl-ctrl-bottom-left { bottom: 0; left: 0; } 63 | .mapboxgl-ctrl-bottom-right { right: 0; bottom: 0; } 64 | 65 | .mapboxgl-ctrl { 66 | clear: both; 67 | pointer-events: auto; 68 | 69 | /* workaround for a Safari bug https://github.com/mapbox/mapbox-gl-js/issues/8185 */ 70 | transform: translate(0, 0); 71 | } 72 | .mapboxgl-ctrl-top-left .mapboxgl-ctrl { margin: 10px 0 0 10px; float: left; } 73 | .mapboxgl-ctrl-top-right .mapboxgl-ctrl { margin: 10px 10px 0 0; float: right; } 74 | .mapboxgl-ctrl-bottom-left .mapboxgl-ctrl { margin: 0 0 10px 10px; float: left; } 75 | .mapboxgl-ctrl-bottom-right .mapboxgl-ctrl { margin: 0 10px 10px 0; float: right; } 76 | 77 | .mapboxgl-ctrl-group { 78 | border-radius: 4px; 79 | overflow: hidden; 80 | background: #fff; 81 | } 82 | 83 | .mapboxgl-ctrl-group:not(:empty) { 84 | -moz-box-shadow: 0 0 2px rgba(0, 0, 0, 0.1); 85 | -webkit-box-shadow: 0 0 2px rgba(0, 0, 0, 0.1); 86 | box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.1); 87 | } 88 | 89 | .mapboxgl-ctrl-group > button { 90 | width: 30px; 91 | height: 30px; 92 | display: block; 93 | padding: 0; 94 | outline: none; 95 | border: 0; 96 | box-sizing: border-box; 97 | background-color: transparent; 98 | cursor: pointer; 99 | } 100 | 101 | .mapboxgl-ctrl-group > button + button { 102 | border-top: 1px solid #ddd; 103 | } 104 | 105 | /* https://bugzilla.mozilla.org/show_bug.cgi?id=140562 */ 106 | .mapboxgl-ctrl > button::-moz-focus-inner { 107 | border: 0; 108 | padding: 0; 109 | } 110 | 111 | .mapboxgl-ctrl > button:hover { 112 | background-color: rgba(0, 0, 0, 0.05); 113 | } 114 | 115 | .mapboxgl-ctrl-icon, 116 | .mapboxgl-ctrl-icon > .mapboxgl-ctrl-compass-arrow { 117 | speak: none; 118 | -webkit-font-smoothing: antialiased; 119 | -moz-osx-font-smoothing: grayscale; 120 | } 121 | 122 | .mapboxgl-ctrl-icon { 123 | padding: 5px; 124 | } 125 | 126 | .mapboxgl-ctrl-icon.mapboxgl-ctrl-icon-disabled { 127 | opacity: 0.25; 128 | border-color: #373737; 129 | } 130 | 131 | .mapboxgl-ctrl-icon.mapboxgl-ctrl-zoom-out { 132 | background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg'%3E %3Cpath style='fill:%23333333;' d='m 7,9 c -0.554,0 -1,0.446 -1,1 0,0.554 0.446,1 1,1 l 6,0 c 0.554,0 1,-0.446 1,-1 0,-0.554 -0.446,-1 -1,-1 z'/%3E %3C/svg%3E"); 133 | } 134 | 135 | .mapboxgl-ctrl-icon.mapboxgl-ctrl-zoom-in { 136 | background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg'%3E %3Cpath style='fill:%23333333;' d='M 10 6 C 9.446 6 9 6.4459904 9 7 L 9 9 L 7 9 C 6.446 9 6 9.446 6 10 C 6 10.554 6.446 11 7 11 L 9 11 L 9 13 C 9 13.55401 9.446 14 10 14 C 10.554 14 11 13.55401 11 13 L 11 11 L 13 11 C 13.554 11 14 10.554 14 10 C 14 9.446 13.554 9 13 9 L 11 9 L 11 7 C 11 6.4459904 10.554 6 10 6 z'/%3E %3C/svg%3E"); 137 | } 138 | 139 | .mapboxgl-ctrl-icon.mapboxgl-ctrl-geolocate::before { 140 | background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg' fill='%23333'%3E %3Cpath d='M10 4C9 4 9 5 9 5L9 5.1A5 5 0 0 0 5.1 9L5 9C5 9 4 9 4 10 4 11 5 11 5 11L5.1 11A5 5 0 0 0 9 14.9L9 15C9 15 9 16 10 16 11 16 11 15 11 15L11 14.9A5 5 0 0 0 14.9 11L15 11C15 11 16 11 16 10 16 9 15 9 15 9L14.9 9A5 5 0 0 0 11 5.1L11 5C11 5 11 4 10 4zM10 6.5A3.5 3.5 0 0 1 13.5 10 3.5 3.5 0 0 1 10 13.5 3.5 3.5 0 0 1 6.5 10 3.5 3.5 0 0 1 10 6.5zM10 8.3A1.8 1.8 0 0 0 8.3 10 1.8 1.8 0 0 0 10 11.8 1.8 1.8 0 0 0 11.8 10 1.8 1.8 0 0 0 10 8.3z'/%3E %3C/svg%3E"); 141 | content: ""; 142 | display: block; 143 | width: 100%; 144 | height: 100%; 145 | } 146 | 147 | .mapboxgl-ctrl-icon.mapboxgl-ctrl-geolocate::before:disabled { 148 | background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg' fill='%23aaa'%3E %3Cpath d='M10 4C9 4 9 5 9 5L9 5.1A5 5 0 0 0 5.1 9L5 9C5 9 4 9 4 10 4 11 5 11 5 11L5.1 11A5 5 0 0 0 9 14.9L9 15C9 15 9 16 10 16 11 16 11 15 11 15L11 14.9A5 5 0 0 0 14.9 11L15 11C15 11 16 11 16 10 16 9 15 9 15 9L14.9 9A5 5 0 0 0 11 5.1L11 5C11 5 11 4 10 4zM10 6.5A3.5 3.5 0 0 1 13.5 10 3.5 3.5 0 0 1 10 13.5 3.5 3.5 0 0 1 6.5 10 3.5 3.5 0 0 1 10 6.5zM10 8.3A1.8 1.8 0 0 0 8.3 10 1.8 1.8 0 0 0 10 11.8 1.8 1.8 0 0 0 11.8 10 1.8 1.8 0 0 0 10 8.3z'/%3E %3C/svg%3E"); 149 | } 150 | 151 | .mapboxgl-ctrl-icon.mapboxgl-ctrl-geolocate.mapboxgl-ctrl-geolocate-active::before { 152 | background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg' fill='%2333b5e5'%3E %3Cpath d='M10 4C9 4 9 5 9 5L9 5.1A5 5 0 0 0 5.1 9L5 9C5 9 4 9 4 10 4 11 5 11 5 11L5.1 11A5 5 0 0 0 9 14.9L9 15C9 15 9 16 10 16 11 16 11 15 11 15L11 14.9A5 5 0 0 0 14.9 11L15 11C15 11 16 11 16 10 16 9 15 9 15 9L14.9 9A5 5 0 0 0 11 5.1L11 5C11 5 11 4 10 4zM10 6.5A3.5 3.5 0 0 1 13.5 10 3.5 3.5 0 0 1 10 13.5 3.5 3.5 0 0 1 6.5 10 3.5 3.5 0 0 1 10 6.5zM10 8.3A1.8 1.8 0 0 0 8.3 10 1.8 1.8 0 0 0 10 11.8 1.8 1.8 0 0 0 11.8 10 1.8 1.8 0 0 0 10 8.3z'/%3E %3C/svg%3E"); 153 | } 154 | 155 | .mapboxgl-ctrl-icon.mapboxgl-ctrl-geolocate.mapboxgl-ctrl-geolocate-active-error::before { 156 | background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg' fill='%23e58978'%3E %3Cpath d='M10 4C9 4 9 5 9 5L9 5.1A5 5 0 0 0 5.1 9L5 9C5 9 4 9 4 10 4 11 5 11 5 11L5.1 11A5 5 0 0 0 9 14.9L9 15C9 15 9 16 10 16 11 16 11 15 11 15L11 14.9A5 5 0 0 0 14.9 11L15 11C15 11 16 11 16 10 16 9 15 9 15 9L14.9 9A5 5 0 0 0 11 5.1L11 5C11 5 11 4 10 4zM10 6.5A3.5 3.5 0 0 1 13.5 10 3.5 3.5 0 0 1 10 13.5 3.5 3.5 0 0 1 6.5 10 3.5 3.5 0 0 1 10 6.5zM10 8.3A1.8 1.8 0 0 0 8.3 10 1.8 1.8 0 0 0 10 11.8 1.8 1.8 0 0 0 11.8 10 1.8 1.8 0 0 0 10 8.3z'/%3E %3C/svg%3E"); 157 | } 158 | 159 | .mapboxgl-ctrl-icon.mapboxgl-ctrl-geolocate.mapboxgl-ctrl-geolocate-background::before { 160 | background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg' fill='%2333b5e5'%3E %3Cpath d='M 10,4 C 9,4 9,5 9,5 L 9,5.1 C 7.0357113,5.5006048 5.5006048,7.0357113 5.1,9 L 5,9 c 0,0 -1,0 -1,1 0,1 1,1 1,1 l 0.1,0 c 0.4006048,1.964289 1.9357113,3.499395 3.9,3.9 L 9,15 c 0,0 0,1 1,1 1,0 1,-1 1,-1 l 0,-0.1 c 1.964289,-0.400605 3.499395,-1.935711 3.9,-3.9 l 0.1,0 c 0,0 1,0 1,-1 C 16,9 15,9 15,9 L 14.9,9 C 14.499395,7.0357113 12.964289,5.5006048 11,5.1 L 11,5 c 0,0 0,-1 -1,-1 z m 0,2.5 c 1.932997,0 3.5,1.5670034 3.5,3.5 0,1.932997 -1.567003,3.5 -3.5,3.5 C 8.0670034,13.5 6.5,11.932997 6.5,10 6.5,8.0670034 8.0670034,6.5 10,6.5 Z'/%3E %3C/svg%3E"); 161 | } 162 | 163 | .mapboxgl-ctrl-icon.mapboxgl-ctrl-geolocate.mapboxgl-ctrl-geolocate-background-error::before { 164 | background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg' fill='%23e54e33'%3E %3Cpath d='M 10,4 C 9,4 9,5 9,5 L 9,5.1 C 7.0357113,5.5006048 5.5006048,7.0357113 5.1,9 L 5,9 c 0,0 -1,0 -1,1 0,1 1,1 1,1 l 0.1,0 c 0.4006048,1.964289 1.9357113,3.499395 3.9,3.9 L 9,15 c 0,0 0,1 1,1 1,0 1,-1 1,-1 l 0,-0.1 c 1.964289,-0.400605 3.499395,-1.935711 3.9,-3.9 l 0.1,0 c 0,0 1,0 1,-1 C 16,9 15,9 15,9 L 14.9,9 C 14.499395,7.0357113 12.964289,5.5006048 11,5.1 L 11,5 c 0,0 0,-1 -1,-1 z m 0,2.5 c 1.932997,0 3.5,1.5670034 3.5,3.5 0,1.932997 -1.567003,3.5 -3.5,3.5 C 8.0670034,13.5 6.5,11.932997 6.5,10 6.5,8.0670034 8.0670034,6.5 10,6.5 Z'/%3E %3C/svg%3E"); 165 | } 166 | 167 | .mapboxgl-ctrl-icon.mapboxgl-ctrl-geolocate.mapboxgl-ctrl-geolocate-waiting::before { 168 | -webkit-animation: mapboxgl-spin 2s infinite linear; 169 | -moz-animation: mapboxgl-spin 2s infinite linear; 170 | -o-animation: mapboxgl-spin 2s infinite linear; 171 | -ms-animation: mapboxgl-spin 2s infinite linear; 172 | animation: mapboxgl-spin 2s infinite linear; 173 | } 174 | 175 | @-webkit-keyframes mapboxgl-spin { 176 | 0% { -webkit-transform: rotate(0deg); } 177 | 100% { -webkit-transform: rotate(360deg); } 178 | } 179 | 180 | @-moz-keyframes mapboxgl-spin { 181 | 0% { -moz-transform: rotate(0deg); } 182 | 100% { -moz-transform: rotate(360deg); } 183 | } 184 | 185 | @-o-keyframes mapboxgl-spin { 186 | 0% { -o-transform: rotate(0deg); } 187 | 100% { -o-transform: rotate(360deg); } 188 | } 189 | 190 | @-ms-keyframes mapboxgl-spin { 191 | 0% { -ms-transform: rotate(0deg); } 192 | 100% { -ms-transform: rotate(360deg); } 193 | } 194 | 195 | @keyframes mapboxgl-spin { 196 | 0% { transform: rotate(0deg); } 197 | 100% { transform: rotate(360deg); } 198 | } 199 | 200 | .mapboxgl-ctrl-icon.mapboxgl-ctrl-fullscreen { 201 | background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg'%3E %3Cpath d='M 5 4 C 4.5 4 4 4.5 4 5 L 4 6 L 4 9 L 4.5 9 L 5.7773438 7.296875 C 6.7771319 8.0602131 7.835765 8.9565728 8.890625 10 C 7.8257121 11.0633 6.7761791 11.951675 5.78125 12.707031 L 4.5 11 L 4 11 L 4 15 C 4 15.5 4.5 16 5 16 L 9 16 L 9 15.5 L 7.2734375 14.205078 C 8.0428931 13.187886 8.9395441 12.133481 9.9609375 11.068359 C 11.042371 12.14699 11.942093 13.2112 12.707031 14.21875 L 11 15.5 L 11 16 L 14 16 L 15 16 C 15.5 16 16 15.5 16 15 L 16 14 L 16 11 L 15.5 11 L 14.205078 12.726562 C 13.177985 11.949617 12.112718 11.043577 11.037109 10.009766 C 12.151856 8.981061 13.224345 8.0798624 14.228516 7.3046875 L 15.5 9 L 16 9 L 16 5 C 16 4.5 15.5 4 15 4 L 11 4 L 11 4.5 L 12.703125 5.7773438 C 11.932647 6.7864834 11.026693 7.8554712 9.9707031 8.9199219 C 8.9584739 7.8204943 8.0698767 6.7627188 7.3046875 5.7714844 L 9 4.5 L 9 4 L 6 4 L 5 4 z '/%3E %3C/svg%3E"); 202 | } 203 | 204 | .mapboxgl-ctrl-icon.mapboxgl-ctrl-shrink { 205 | background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg'%3E %3Cpath style='fill:%23000000;' d='M 4.2421875 3.4921875 A 0.750075 0.750075 0 0 0 3.71875 4.78125 L 5.9648438 7.0273438 L 4 8.5 L 4 9 L 8 9 C 8.500001 8.9999988 9 8.4999992 9 8 L 9 4 L 8.5 4 L 7.0175781 5.9550781 L 4.78125 3.71875 A 0.750075 0.750075 0 0 0 4.2421875 3.4921875 z M 15.734375 3.4921875 A 0.750075 0.750075 0 0 0 15.21875 3.71875 L 12.984375 5.953125 L 11.5 4 L 11 4 L 11 8 C 11 8.4999992 11.499999 8.9999988 12 9 L 16 9 L 16 8.5 L 14.035156 7.0273438 L 16.28125 4.78125 A 0.750075 0.750075 0 0 0 15.734375 3.4921875 z M 4 11 L 4 11.5 L 5.9648438 12.972656 L 3.71875 15.21875 A 0.75130096 0.75130096 0 1 0 4.78125 16.28125 L 7.0273438 14.035156 L 8.5 16 L 9 16 L 9 12 C 9 11.500001 8.500001 11.000001 8 11 L 4 11 z M 12 11 C 11.499999 11.000001 11 11.500001 11 12 L 11 16 L 11.5 16 L 12.972656 14.035156 L 15.21875 16.28125 A 0.75130096 0.75130096 0 1 0 16.28125 15.21875 L 14.035156 12.972656 L 16 11.5 L 16 11 L 12 11 z '/%3E %3C/svg%3E"); 206 | } 207 | 208 | .mapboxgl-ctrl-icon.mapboxgl-ctrl-compass > .mapboxgl-ctrl-compass-arrow { 209 | width: 20px; 210 | height: 20px; 211 | margin: 5px; 212 | background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg'%3E %3Cpolygon fill='%23333333' points='6,9 10,1 14,9'/%3E %3Cpolygon fill='%23CCCCCC' points='6,11 10,19 14,11 '/%3E %3C/svg%3E"); 213 | background-repeat: no-repeat; 214 | display: inline-block; 215 | } 216 | 217 | a.mapboxgl-ctrl-logo { 218 | width: 85px; 219 | height: 21px; 220 | margin: 0 0 -3px -3px; 221 | display: block; 222 | background-repeat: no-repeat; 223 | cursor: pointer; 224 | background-image: url("data:image/svg+xml;charset=utf-8,%3C?xml version='1.0' encoding='utf-8'?%3E%3Csvg version='1.1' id='Layer_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 84.49 21' style='enable-background:new 0 0 84.49 21;' xml:space='preserve'%3E%3Cg%3E %3Cpath class='st0' style='opacity:0.9; fill: %23FFFFFF; enable-background: new;' d='M83.25,14.26c0,0.12-0.09,0.21-0.21,0.21h-1.61c-0.13,0-0.24-0.06-0.3-0.17l-1.44-2.39l-1.44,2.39 c-0.06,0.11-0.18,0.17-0.3,0.17h-1.61c-0.04,0-0.08-0.01-0.12-0.03c-0.09-0.06-0.13-0.19-0.06-0.28l0,0l2.43-3.68L76.2,6.84 c-0.02-0.03-0.03-0.07-0.03-0.12c0-0.12,0.09-0.21,0.21-0.21h1.61c0.13,0,0.24,0.06,0.3,0.17l1.41,2.36l1.4-2.35 c0.06-0.11,0.18-0.17,0.3-0.17H83c0.04,0,0.08,0.01,0.12,0.03c0.09,0.06,0.13,0.19,0.06,0.28l0,0l-2.37,3.63l2.43,3.67 C83.24,14.18,83.25,14.22,83.25,14.26z'/%3E %3Cpath class='st0' style='opacity:0.9; fill: %23FFFFFF; enable-background: new;' d='M66.24,9.59c-0.39-1.88-1.96-3.28-3.84-3.28c-1.03,0-2.03,0.42-2.73,1.18V3.51c0-0.13-0.1-0.23-0.23-0.23h-1.4 c-0.13,0-0.23,0.11-0.23,0.23v10.72c0,0.13,0.1,0.23,0.23,0.23h1.4c0.13,0,0.23-0.11,0.23-0.23V13.5c0.71,0.75,1.7,1.18,2.73,1.18 c1.88,0,3.45-1.41,3.84-3.29C66.37,10.79,66.37,10.18,66.24,9.59L66.24,9.59z M62.08,13c-1.32,0-2.39-1.11-2.41-2.48v-0.06 c0.02-1.38,1.09-2.48,2.41-2.48s2.42,1.12,2.42,2.51S63.41,13,62.08,13z'/%3E %3Cpath class='st0' style='opacity:0.9; fill: %23FFFFFF; enable-background: new;' d='M71.67,6.32c-1.98-0.01-3.72,1.35-4.16,3.29c-0.13,0.59-0.13,1.19,0,1.77c0.44,1.94,2.17,3.32,4.17,3.3 c2.35,0,4.26-1.87,4.26-4.19S74.04,6.32,71.67,6.32z M71.65,13.01c-1.33,0-2.42-1.12-2.42-2.51s1.08-2.52,2.42-2.52 c1.33,0,2.42,1.12,2.42,2.51S72.99,13,71.65,13.01L71.65,13.01z'/%3E %3Cpath class='st1' style='opacity:0.35; enable-background:new;' d='M62.08,7.98c-1.32,0-2.39,1.11-2.41,2.48v0.06C59.68,11.9,60.75,13,62.08,13s2.42-1.12,2.42-2.51 S63.41,7.98,62.08,7.98z M62.08,11.76c-0.63,0-1.14-0.56-1.17-1.25v-0.04c0.01-0.69,0.54-1.25,1.17-1.25 c0.63,0,1.17,0.57,1.17,1.27C63.24,11.2,62.73,11.76,62.08,11.76z'/%3E %3Cpath class='st1' style='opacity:0.35; enable-background:new;' d='M71.65,7.98c-1.33,0-2.42,1.12-2.42,2.51S70.32,13,71.65,13s2.42-1.12,2.42-2.51S72.99,7.98,71.65,7.98z M71.65,11.76c-0.64,0-1.17-0.57-1.17-1.27c0-0.7,0.53-1.26,1.17-1.26s1.17,0.57,1.17,1.27C72.82,11.21,72.29,11.76,71.65,11.76z'/%3E %3Cpath class='st0' style='opacity:0.9; fill: %23FFFFFF; enable-background: new;' d='M45.74,6.53h-1.4c-0.13,0-0.23,0.11-0.23,0.23v0.73c-0.71-0.75-1.7-1.18-2.73-1.18 c-2.17,0-3.94,1.87-3.94,4.19s1.77,4.19,3.94,4.19c1.04,0,2.03-0.43,2.73-1.19v0.73c0,0.13,0.1,0.23,0.23,0.23h1.4 c0.13,0,0.23-0.11,0.23-0.23V6.74c0-0.12-0.09-0.22-0.22-0.22C45.75,6.53,45.75,6.53,45.74,6.53z M44.12,10.53 C44.11,11.9,43.03,13,41.71,13s-2.42-1.12-2.42-2.51s1.08-2.52,2.4-2.52c1.33,0,2.39,1.11,2.41,2.48L44.12,10.53z'/%3E %3Cpath class='st1' style='opacity:0.35; enable-background:new;' d='M41.71,7.98c-1.33,0-2.42,1.12-2.42,2.51S40.37,13,41.71,13s2.39-1.11,2.41-2.48v-0.06 C44.1,9.09,43.03,7.98,41.71,7.98z M40.55,10.49c0-0.7,0.52-1.27,1.17-1.27c0.64,0,1.14,0.56,1.17,1.25v0.04 c-0.01,0.68-0.53,1.24-1.17,1.24C41.08,11.75,40.55,11.19,40.55,10.49z'/%3E %3Cpath class='st0' style='opacity:0.9; fill: %23FFFFFF; enable-background: new;' d='M52.41,6.32c-1.03,0-2.03,0.42-2.73,1.18V6.75c0-0.13-0.1-0.23-0.23-0.23h-1.4c-0.13,0-0.23,0.11-0.23,0.23 v10.72c0,0.13,0.1,0.23,0.23,0.23h1.4c0.13,0,0.23-0.1,0.23-0.23V13.5c0.71,0.75,1.7,1.18,2.74,1.18c2.17,0,3.94-1.87,3.94-4.19 S54.58,6.32,52.41,6.32z M52.08,13.01c-1.32,0-2.39-1.11-2.42-2.48v-0.07c0.02-1.38,1.09-2.49,2.4-2.49c1.32,0,2.41,1.12,2.41,2.51 S53.4,13,52.08,13.01L52.08,13.01z'/%3E %3Cpath class='st1' style='opacity:0.35; enable-background:new;' d='M52.08,7.98c-1.32,0-2.39,1.11-2.42,2.48v0.06c0.03,1.38,1.1,2.48,2.42,2.48s2.41-1.12,2.41-2.51 S53.4,7.98,52.08,7.98z M52.08,11.76c-0.63,0-1.14-0.56-1.17-1.25v-0.04c0.01-0.69,0.54-1.25,1.17-1.25c0.63,0,1.17,0.58,1.17,1.27 S52.72,11.76,52.08,11.76z'/%3E %3Cpath class='st0' style='opacity:0.9; fill: %23FFFFFF; enable-background: new;' d='M36.08,14.24c0,0.13-0.1,0.23-0.23,0.23h-1.41c-0.13,0-0.23-0.11-0.23-0.23V9.68c0-0.98-0.74-1.71-1.62-1.71 c-0.8,0-1.46,0.7-1.59,1.62l0.01,4.66c0,0.13-0.11,0.23-0.23,0.23h-1.41c-0.13,0-0.23-0.11-0.23-0.23V9.68 c0-0.98-0.74-1.71-1.62-1.71c-0.85,0-1.54,0.79-1.6,1.8v4.48c0,0.13-0.1,0.23-0.23,0.23h-1.4c-0.13,0-0.23-0.11-0.23-0.23V6.74 c0.01-0.13,0.1-0.22,0.23-0.22h1.4c0.13,0,0.22,0.11,0.23,0.22V7.4c0.5-0.68,1.3-1.09,2.16-1.1h0.03c1.09,0,2.09,0.6,2.6,1.55 c0.45-0.95,1.4-1.55,2.44-1.56c1.62,0,2.93,1.25,2.9,2.78L36.08,14.24z'/%3E %3Cpath class='st1' style='opacity:0.35; enable-background:new;' d='M84.34,13.59l-0.07-0.13l-1.96-2.99l1.94-2.95c0.44-0.67,0.26-1.56-0.41-2.02c-0.02,0-0.03,0-0.04-0.01 c-0.23-0.15-0.5-0.22-0.78-0.22h-1.61c-0.56,0-1.08,0.29-1.37,0.78L79.72,6.6l-0.34-0.56C79.09,5.56,78.57,5.27,78,5.27h-1.6 c-0.6,0-1.13,0.37-1.35,0.92c-2.19-1.66-5.28-1.47-7.26,0.45c-0.35,0.34-0.65,0.72-0.89,1.14c-0.9-1.62-2.58-2.72-4.5-2.72 c-0.5,0-1.01,0.07-1.48,0.23V3.51c0-0.82-0.66-1.48-1.47-1.48h-1.4c-0.81,0-1.47,0.66-1.47,1.47v3.75 c-0.95-1.36-2.5-2.18-4.17-2.19c-0.74,0-1.46,0.16-2.12,0.47c-0.24-0.17-0.54-0.26-0.84-0.26h-1.4c-0.45,0-0.87,0.21-1.15,0.56 c-0.02-0.03-0.04-0.05-0.07-0.08c-0.28-0.3-0.68-0.47-1.09-0.47h-1.39c-0.3,0-0.6,0.09-0.84,0.26c-0.67-0.3-1.39-0.46-2.12-0.46 c-1.83,0-3.43,1-4.37,2.5c-0.2-0.46-0.48-0.89-0.83-1.25c-0.8-0.81-1.89-1.25-3.02-1.25h-0.01c-0.89,0.01-1.75,0.33-2.46,0.88 c-0.74-0.57-1.64-0.88-2.57-0.88H28.1c-0.29,0-0.58,0.03-0.86,0.11c-0.28,0.06-0.56,0.16-0.82,0.28c-0.21-0.12-0.45-0.18-0.7-0.18 h-1.4c-0.82,0-1.47,0.66-1.47,1.47v7.5c0,0.82,0.66,1.47,1.47,1.47h1.4c0.82,0,1.48-0.66,1.48-1.48l0,0V9.79 c0.03-0.36,0.23-0.59,0.36-0.59c0.18,0,0.38,0.18,0.38,0.47v4.57c0,0.82,0.66,1.47,1.47,1.47h1.41c0.82,0,1.47-0.66,1.47-1.47 l-0.01-4.57c0.06-0.32,0.25-0.47,0.35-0.47c0.18,0,0.38,0.18,0.38,0.47v4.57c0,0.82,0.66,1.47,1.47,1.47h1.41 c0.82,0,1.47-0.66,1.47-1.47v-0.38c0.96,1.29,2.46,2.06,4.06,2.06c0.74,0,1.46-0.16,2.12-0.47c0.24,0.17,0.54,0.26,0.84,0.26h1.39 c0.3,0,0.6-0.09,0.84-0.26v2.01c0,0.82,0.66,1.47,1.47,1.47h1.4c0.82,0,1.47-0.66,1.47-1.47v-1.77c0.48,0.15,0.99,0.23,1.49,0.22 c1.7,0,3.22-0.87,4.17-2.2v0.52c0,0.82,0.66,1.47,1.47,1.47h1.4c0.3,0,0.6-0.09,0.84-0.26c0.66,0.31,1.39,0.47,2.12,0.47 c1.92,0,3.6-1.1,4.49-2.73c1.54,2.65,4.95,3.53,7.58,1.98c0.18-0.11,0.36-0.22,0.53-0.36c0.22,0.55,0.76,0.91,1.35,0.9H78 c0.56,0,1.08-0.29,1.37-0.78l0.37-0.61l0.37,0.61c0.29,0.48,0.81,0.78,1.38,0.78h1.6c0.81,0,1.46-0.66,1.45-1.46 C84.49,14.02,84.44,13.8,84.34,13.59L84.34,13.59z M35.86,14.47h-1.41c-0.13,0-0.23-0.11-0.23-0.23V9.68 c0-0.98-0.74-1.71-1.62-1.71c-0.8,0-1.46,0.7-1.59,1.62l0.01,4.66c0,0.13-0.1,0.23-0.23,0.23h-1.41c-0.13,0-0.23-0.11-0.23-0.23 V9.68c0-0.98-0.74-1.71-1.62-1.71c-0.85,0-1.54,0.79-1.6,1.8v4.48c0,0.13-0.1,0.23-0.23,0.23h-1.4c-0.13,0-0.23-0.11-0.23-0.23 V6.74c0.01-0.13,0.11-0.22,0.23-0.22h1.4c0.13,0,0.22,0.11,0.23,0.22V7.4c0.5-0.68,1.3-1.09,2.16-1.1h0.03 c1.09,0,2.09,0.6,2.6,1.55c0.45-0.95,1.4-1.55,2.44-1.56c1.62,0,2.93,1.25,2.9,2.78l0.01,5.16C36.09,14.36,35.98,14.46,35.86,14.47 L35.86,14.47z M45.97,14.24c0,0.13-0.1,0.23-0.23,0.23h-1.4c-0.13,0-0.23-0.11-0.23-0.23V13.5c-0.7,0.76-1.69,1.18-2.72,1.18 c-2.17,0-3.94-1.87-3.94-4.19s1.77-4.19,3.94-4.19c1.03,0,2.02,0.43,2.73,1.18V6.74c0-0.13,0.1-0.23,0.23-0.23h1.4 c0.12-0.01,0.22,0.08,0.23,0.21c0,0.01,0,0.01,0,0.02v7.51h-0.01V14.24z M52.41,14.67c-1.03,0-2.02-0.43-2.73-1.18v3.97 c0,0.13-0.1,0.23-0.23,0.23h-1.4c-0.13,0-0.23-0.1-0.23-0.23V6.75c0-0.13,0.1-0.22,0.23-0.22h1.4c0.13,0,0.23,0.11,0.23,0.23v0.73 c0.71-0.76,1.7-1.18,2.73-1.18c2.17,0,3.94,1.86,3.94,4.18S54.58,14.67,52.41,14.67z M66.24,11.39c-0.39,1.87-1.96,3.29-3.84,3.29 c-1.03,0-2.02-0.43-2.73-1.18v0.73c0,0.13-0.1,0.23-0.23,0.23h-1.4c-0.13,0-0.23-0.11-0.23-0.23V3.51c0-0.13,0.1-0.23,0.23-0.23 h1.4c0.13,0,0.23,0.11,0.23,0.23v3.97c0.71-0.75,1.7-1.18,2.73-1.17c1.88,0,3.45,1.4,3.84,3.28C66.37,10.19,66.37,10.8,66.24,11.39 L66.24,11.39L66.24,11.39z M71.67,14.68c-2,0.01-3.73-1.35-4.17-3.3c-0.13-0.59-0.13-1.19,0-1.77c0.44-1.94,2.17-3.31,4.17-3.3 c2.36,0,4.26,1.87,4.26,4.19S74.03,14.68,71.67,14.68L71.67,14.68z M83.04,14.47h-1.61c-0.13,0-0.24-0.06-0.3-0.17l-1.44-2.39 l-1.44,2.39c-0.06,0.11-0.18,0.17-0.3,0.17h-1.61c-0.04,0-0.08-0.01-0.12-0.03c-0.09-0.06-0.13-0.19-0.06-0.28l0,0l2.43-3.68 L76.2,6.84c-0.02-0.03-0.03-0.07-0.03-0.12c0-0.12,0.09-0.21,0.21-0.21h1.61c0.13,0,0.24,0.06,0.3,0.17l1.41,2.36l1.41-2.36 c0.06-0.11,0.18-0.17,0.3-0.17h1.61c0.04,0,0.08,0.01,0.12,0.03c0.09,0.06,0.13,0.19,0.06,0.28l0,0l-2.38,3.64l2.43,3.67 c0.02,0.03,0.03,0.07,0.03,0.12C83.25,14.38,83.16,14.47,83.04,14.47L83.04,14.47L83.04,14.47z'/%3E %3Cpath class='st0' style='opacity:0.9; fill: %23FFFFFF; enable-background: new;' d='M10.5,1.24c-5.11,0-9.25,4.15-9.25,9.25s4.15,9.25,9.25,9.25s9.25-4.15,9.25-9.25 C19.75,5.38,15.61,1.24,10.5,1.24z M14.89,12.77c-1.93,1.93-4.78,2.31-6.7,2.31c-0.7,0-1.41-0.05-2.1-0.16c0,0-1.02-5.64,2.14-8.81 c0.83-0.83,1.95-1.28,3.13-1.28c1.27,0,2.49,0.51,3.39,1.42C16.59,8.09,16.64,11,14.89,12.77z'/%3E %3Cpath class='st1' style='opacity:0.35; enable-background:new;' d='M10.5-0.01C4.7-0.01,0,4.7,0,10.49s4.7,10.5,10.5,10.5S21,16.29,21,10.49C20.99,4.7,16.3-0.01,10.5-0.01z M10.5,19.74c-5.11,0-9.25-4.15-9.25-9.25s4.14-9.26,9.25-9.26s9.25,4.15,9.25,9.25C19.75,15.61,15.61,19.74,10.5,19.74z'/%3E %3Cpath class='st1' style='opacity:0.35; enable-background:new;' d='M14.74,6.25C12.9,4.41,9.98,4.35,8.23,6.1c-3.16,3.17-2.14,8.81-2.14,8.81s5.64,1.02,8.81-2.14 C16.64,11,16.59,8.09,14.74,6.25z M12.47,10.34l-0.91,1.87l-0.9-1.87L8.8,9.43l1.86-0.9l0.9-1.87l0.91,1.87l1.86,0.9L12.47,10.34z'/%3E %3Cpolygon class='st0' style='opacity:0.9; fill: %23FFFFFF; enable-background: new;' points='14.33,9.43 12.47,10.34 11.56,12.21 10.66,10.34 8.8,9.43 10.66,8.53 11.56,6.66 12.47,8.53 '/%3E%3C/g%3E%3C/svg%3E"); 225 | } 226 | 227 | a.mapboxgl-ctrl-logo.mapboxgl-compact { 228 | width: 21px; 229 | height: 21px; 230 | background-image: url("data:image/svg+xml;charset=utf-8,%3C?xml version='1.0' encoding='utf-8'?%3E %3Csvg version='1.1' id='Layer_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 21 21' style='enable-background:new 0 0 21 21;' xml:space='preserve'%3E%3Cg transform='translate(0,0.01)'%3E%3Cpath d='m 10.5,1.24 c -5.11,0 -9.25,4.15 -9.25,9.25 0,5.1 4.15,9.25 9.25,9.25 5.1,0 9.25,-4.15 9.25,-9.25 0,-5.11 -4.14,-9.25 -9.25,-9.25 z m 4.39,11.53 c -1.93,1.93 -4.78,2.31 -6.7,2.31 -0.7,0 -1.41,-0.05 -2.1,-0.16 0,0 -1.02,-5.64 2.14,-8.81 0.83,-0.83 1.95,-1.28 3.13,-1.28 1.27,0 2.49,0.51 3.39,1.42 1.84,1.84 1.89,4.75 0.14,6.52 z' style='opacity:0.9;fill:%23ffffff;enable-background:new' class='st0'/%3E%3Cpath d='M 10.5,-0.01 C 4.7,-0.01 0,4.7 0,10.49 c 0,5.79 4.7,10.5 10.5,10.5 5.8,0 10.5,-4.7 10.5,-10.5 C 20.99,4.7 16.3,-0.01 10.5,-0.01 Z m 0,19.75 c -5.11,0 -9.25,-4.15 -9.25,-9.25 0,-5.1 4.14,-9.26 9.25,-9.26 5.11,0 9.25,4.15 9.25,9.25 0,5.13 -4.14,9.26 -9.25,9.26 z' style='opacity:0.35;enable-background:new' class='st1'/%3E%3Cpath d='M 14.74,6.25 C 12.9,4.41 9.98,4.35 8.23,6.1 5.07,9.27 6.09,14.91 6.09,14.91 c 0,0 5.64,1.02 8.81,-2.14 C 16.64,11 16.59,8.09 14.74,6.25 Z m -2.27,4.09 -0.91,1.87 -0.9,-1.87 -1.86,-0.91 1.86,-0.9 0.9,-1.87 0.91,1.87 1.86,0.9 z' style='opacity:0.35;enable-background:new' class='st1'/%3E%3Cpolygon points='11.56,12.21 10.66,10.34 8.8,9.43 10.66,8.53 11.56,6.66 12.47,8.53 14.33,9.43 12.47,10.34 ' style='opacity:0.9;fill:%23ffffff;enable-background:new' class='st0'/%3E%3C/g%3E%3C/svg%3E"); 231 | } 232 | 233 | .mapboxgl-ctrl.mapboxgl-ctrl-attrib { 234 | padding: 0 5px; 235 | background-color: rgba(255, 255, 255, 0.5); 236 | margin: 0; 237 | } 238 | 239 | @media screen { 240 | .mapboxgl-ctrl-attrib.mapboxgl-compact { 241 | min-height: 20px; 242 | padding: 0; 243 | margin: 10px; 244 | position: relative; 245 | background-color: #fff; 246 | border-radius: 3px 12px 12px 3px; 247 | } 248 | 249 | .mapboxgl-ctrl-attrib.mapboxgl-compact:hover { 250 | padding: 2px 24px 2px 4px; 251 | visibility: visible; 252 | margin-top: 6px; 253 | } 254 | 255 | .mapboxgl-ctrl-top-left > .mapboxgl-ctrl-attrib.mapboxgl-compact:hover, 256 | .mapboxgl-ctrl-bottom-left > .mapboxgl-ctrl-attrib.mapboxgl-compact:hover { 257 | padding: 2px 4px 2px 24px; 258 | border-radius: 12px 3px 3px 12px; 259 | } 260 | 261 | .mapboxgl-ctrl-attrib.mapboxgl-compact .mapboxgl-ctrl-attrib-inner { 262 | display: none; 263 | } 264 | 265 | .mapboxgl-ctrl-attrib.mapboxgl-compact:hover .mapboxgl-ctrl-attrib-inner { 266 | display: block; 267 | } 268 | 269 | .mapboxgl-ctrl-attrib.mapboxgl-compact::after { 270 | content: ''; 271 | cursor: pointer; 272 | position: absolute; 273 | background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg'%3E %3Cpath fill='%23333333' fill-rule='evenodd' d='M4,10a6,6 0 1,0 12,0a6,6 0 1,0 -12,0 M9,7a1,1 0 1,0 2,0a1,1 0 1,0 -2,0 M9,10a1,1 0 1,1 2,0l0,3a1,1 0 1,1 -2,0'/%3E %3C/svg%3E"); 274 | background-color: rgba(255, 255, 255, 0.5); 275 | width: 24px; 276 | height: 24px; 277 | box-sizing: border-box; 278 | border-radius: 12px; 279 | } 280 | 281 | .mapboxgl-ctrl-bottom-right > .mapboxgl-ctrl-attrib.mapboxgl-compact::after { 282 | bottom: 0; 283 | right: 0; 284 | } 285 | 286 | .mapboxgl-ctrl-top-right > .mapboxgl-ctrl-attrib.mapboxgl-compact::after { 287 | top: 0; 288 | right: 0; 289 | } 290 | 291 | .mapboxgl-ctrl-top-left > .mapboxgl-ctrl-attrib.mapboxgl-compact::after { 292 | top: 0; 293 | left: 0; 294 | } 295 | 296 | .mapboxgl-ctrl-bottom-left > .mapboxgl-ctrl-attrib.mapboxgl-compact::after { 297 | bottom: 0; 298 | left: 0; 299 | } 300 | } 301 | 302 | .mapboxgl-ctrl-attrib a { 303 | color: rgba(0, 0, 0, 0.75); 304 | text-decoration: none; 305 | } 306 | 307 | .mapboxgl-ctrl-attrib a:hover { 308 | color: inherit; 309 | text-decoration: underline; 310 | } 311 | 312 | /* stylelint-disable-next-line selector-class-pattern */ 313 | .mapboxgl-ctrl-attrib .mapbox-improve-map { 314 | font-weight: bold; 315 | margin-left: 2px; 316 | } 317 | 318 | .mapboxgl-attrib-empty { 319 | display: none; 320 | } 321 | 322 | .mapboxgl-ctrl-scale { 323 | background-color: rgba(255, 255, 255, 0.75); 324 | font-size: 10px; 325 | border-width: medium 2px 2px; 326 | border-style: none solid solid; 327 | border-color: #333; 328 | padding: 0 5px; 329 | color: #333; 330 | box-sizing: border-box; 331 | } 332 | 333 | .mapboxgl-popup { 334 | position: absolute; 335 | top: 0; 336 | left: 0; 337 | display: -webkit-flex; 338 | display: flex; 339 | will-change: transform; 340 | pointer-events: none; 341 | } 342 | 343 | .mapboxgl-popup-anchor-top, 344 | .mapboxgl-popup-anchor-top-left, 345 | .mapboxgl-popup-anchor-top-right { 346 | -webkit-flex-direction: column; 347 | flex-direction: column; 348 | } 349 | 350 | .mapboxgl-popup-anchor-bottom, 351 | .mapboxgl-popup-anchor-bottom-left, 352 | .mapboxgl-popup-anchor-bottom-right { 353 | -webkit-flex-direction: column-reverse; 354 | flex-direction: column-reverse; 355 | } 356 | 357 | .mapboxgl-popup-anchor-left { 358 | -webkit-flex-direction: row; 359 | flex-direction: row; 360 | } 361 | 362 | .mapboxgl-popup-anchor-right { 363 | -webkit-flex-direction: row-reverse; 364 | flex-direction: row-reverse; 365 | } 366 | 367 | .mapboxgl-popup-tip { 368 | width: 0; 369 | height: 0; 370 | border: 10px solid transparent; 371 | z-index: 1; 372 | } 373 | 374 | .mapboxgl-popup-anchor-top .mapboxgl-popup-tip { 375 | -webkit-align-self: center; 376 | align-self: center; 377 | border-top: none; 378 | border-bottom-color: #fff; 379 | } 380 | 381 | .mapboxgl-popup-anchor-top-left .mapboxgl-popup-tip { 382 | -webkit-align-self: flex-start; 383 | align-self: flex-start; 384 | border-top: none; 385 | border-left: none; 386 | border-bottom-color: #fff; 387 | } 388 | 389 | .mapboxgl-popup-anchor-top-right .mapboxgl-popup-tip { 390 | -webkit-align-self: flex-end; 391 | align-self: flex-end; 392 | border-top: none; 393 | border-right: none; 394 | border-bottom-color: #fff; 395 | } 396 | 397 | .mapboxgl-popup-anchor-bottom .mapboxgl-popup-tip { 398 | -webkit-align-self: center; 399 | align-self: center; 400 | border-bottom: none; 401 | border-top-color: #fff; 402 | } 403 | 404 | .mapboxgl-popup-anchor-bottom-left .mapboxgl-popup-tip { 405 | -webkit-align-self: flex-start; 406 | align-self: flex-start; 407 | border-bottom: none; 408 | border-left: none; 409 | border-top-color: #fff; 410 | } 411 | 412 | .mapboxgl-popup-anchor-bottom-right .mapboxgl-popup-tip { 413 | -webkit-align-self: flex-end; 414 | align-self: flex-end; 415 | border-bottom: none; 416 | border-right: none; 417 | border-top-color: #fff; 418 | } 419 | 420 | .mapboxgl-popup-anchor-left .mapboxgl-popup-tip { 421 | -webkit-align-self: center; 422 | align-self: center; 423 | border-left: none; 424 | border-right-color: #fff; 425 | } 426 | 427 | .mapboxgl-popup-anchor-right .mapboxgl-popup-tip { 428 | -webkit-align-self: center; 429 | align-self: center; 430 | border-right: none; 431 | border-left-color: #fff; 432 | } 433 | 434 | .mapboxgl-popup-close-button { 435 | position: absolute; 436 | right: 0; 437 | top: 0; 438 | border: 0; 439 | border-radius: 0 3px 0 0; 440 | cursor: pointer; 441 | background-color: transparent; 442 | } 443 | 444 | .mapboxgl-popup-close-button:hover { 445 | background-color: rgba(0, 0, 0, 0.05); 446 | } 447 | 448 | .mapboxgl-popup-content { 449 | position: relative; 450 | background: #fff; 451 | border-radius: 3px; 452 | box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); 453 | padding: 10px 10px 15px; 454 | pointer-events: auto; 455 | } 456 | 457 | .mapboxgl-popup-anchor-top-left .mapboxgl-popup-content { 458 | border-top-left-radius: 0; 459 | } 460 | 461 | .mapboxgl-popup-anchor-top-right .mapboxgl-popup-content { 462 | border-top-right-radius: 0; 463 | } 464 | 465 | .mapboxgl-popup-anchor-bottom-left .mapboxgl-popup-content { 466 | border-bottom-left-radius: 0; 467 | } 468 | 469 | .mapboxgl-popup-anchor-bottom-right .mapboxgl-popup-content { 470 | border-bottom-right-radius: 0; 471 | } 472 | 473 | .mapboxgl-popup-track-pointer { 474 | display: none; 475 | } 476 | 477 | .mapboxgl-popup-track-pointer * { 478 | pointer-events: none; 479 | user-select: none; 480 | } 481 | 482 | .mapboxgl-map:hover .mapboxgl-popup-track-pointer { 483 | display: flex; 484 | } 485 | 486 | .mapboxgl-map:active .mapboxgl-popup-track-pointer { 487 | display: none; 488 | } 489 | 490 | .mapboxgl-marker { 491 | position: absolute; 492 | top: 0; 493 | left: 0; 494 | will-change: transform; 495 | } 496 | 497 | .mapboxgl-user-location-dot { 498 | background-color: #1da1f2; 499 | width: 15px; 500 | height: 15px; 501 | border-radius: 50%; 502 | } 503 | 504 | .mapboxgl-user-location-dot::before { 505 | background-color: #1da1f2; 506 | content: ''; 507 | width: 15px; 508 | height: 15px; 509 | border-radius: 50%; 510 | position: absolute; 511 | -webkit-animation: mapboxgl-user-location-dot-pulse 2s infinite; 512 | -moz-animation: mapboxgl-user-location-dot-pulse 2s infinite; 513 | -ms-animation: mapboxgl-user-location-dot-pulse 2s infinite; 514 | animation: mapboxgl-user-location-dot-pulse 2s infinite; 515 | } 516 | 517 | .mapboxgl-user-location-dot::after { 518 | border-radius: 50%; 519 | border: 2px solid #fff; 520 | content: ''; 521 | height: 19px; 522 | left: -2px; 523 | position: absolute; 524 | top: -2px; 525 | width: 19px; 526 | box-sizing: border-box; 527 | box-shadow: 0 0 3px rgba(0, 0, 0, 0.35); 528 | } 529 | 530 | @-webkit-keyframes mapboxgl-user-location-dot-pulse { 531 | 0% { -webkit-transform: scale(1); opacity: 1; } 532 | 70% { -webkit-transform: scale(3); opacity: 0; } 533 | 100% { -webkit-transform: scale(1); opacity: 0; } 534 | } 535 | 536 | @-ms-keyframes mapboxgl-user-location-dot-pulse { 537 | 0% { -ms-transform: scale(1); opacity: 1; } 538 | 70% { -ms-transform: scale(3); opacity: 0; } 539 | 100% { -ms-transform: scale(1); opacity: 0; } 540 | } 541 | 542 | @keyframes mapboxgl-user-location-dot-pulse { 543 | 0% { transform: scale(1); opacity: 1; } 544 | 70% { transform: scale(3); opacity: 0; } 545 | 100% { transform: scale(1); opacity: 0; } 546 | } 547 | 548 | .mapboxgl-user-location-dot-stale { 549 | background-color: #aaa; 550 | } 551 | 552 | .mapboxgl-user-location-dot-stale::after { 553 | display: none; 554 | } 555 | 556 | .mapboxgl-crosshair, 557 | .mapboxgl-crosshair .mapboxgl-interactive, 558 | .mapboxgl-crosshair .mapboxgl-interactive:active { 559 | cursor: crosshair; 560 | } 561 | 562 | .mapboxgl-boxzoom { 563 | position: absolute; 564 | top: 0; 565 | left: 0; 566 | width: 0; 567 | height: 0; 568 | background: #fff; 569 | border: 2px dotted #202020; 570 | opacity: 0.5; 571 | } 572 | 573 | @media print { 574 | /* stylelint-disable-next-line selector-class-pattern */ 575 | .mapbox-improve-map { 576 | display: none; 577 | } 578 | } 579 | -------------------------------------------------------------------------------- /src/renderer/styles/styles.css: -------------------------------------------------------------------------------- 1 | .map-container { 2 | height: 480px; 3 | width: 100%; 4 | margin: 0px; 5 | background-color: var(--vscode-editor-background) !important; 6 | } 7 | 8 | .unfolded-map { 9 | background-color: var(--vscode-editor-background); 10 | font-family: monospace; 11 | font-size: 12px; 12 | overflow: hidden; 13 | } 14 | 15 | .text-output { 16 | background-color: var(--vscode-editor-background); 17 | border: 1px solid var(--vscode-panel-border); 18 | font-family: var(--vscode-editor-font-family); 19 | font-size: var(--vscode-editor-font-size); 20 | margin-top: 0px; 21 | max-height: 360px; 22 | overflow: auto; 23 | tab-size: 2; 24 | white-space: pre-wrap; 25 | padding: 10px; 26 | } 27 | 28 | .text-output code { 29 | color: var(--vscode-editor-foreground) !important; 30 | } 31 | -------------------------------------------------------------------------------- /src/renderer/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig-base.json", 3 | "compilerOptions": { 4 | // noEmit prevents the default tsc from building this--we use webpack instead 5 | "noEmit": true, 6 | "rootDir": ".", 7 | "module": "esnext", 8 | "lib": ["ES2019", "dom"], 9 | "types": ["webpack-env", "vscode-notebook-renderer"], 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/renderer/unfoldedMap.js: -------------------------------------------------------------------------------- 1 | import { 2 | UnfoldedMap 3 | } from '@unfolded/map-sdk'; 4 | 5 | import * as config from './config'; 6 | 7 | // map settings 8 | const mapTheme = 'light_streets'; // default map theme 9 | 10 | /** 11 | * Creates new map instance. 12 | * @param {*} geoData GeoJSON data to display on the map. 13 | * @param {*} mapContainer Map view container. 14 | * @returns map instance to display. 15 | */ 16 | export function createMap(geoData, mapContainer) { 17 | let map; 18 | try { 19 | console.log('unfolded.map:createMap(): creating map ...'); 20 | map = new UnfoldedMap({ 21 | embed: false, 22 | appendToDocument: false, 23 | height: config.mapHeight, 24 | onLoad: () => { 25 | map.addDataset({ 26 | uuid: 'geojson data', 27 | label: 'Geo Data', 28 | data: JSON.stringify(geoData) 29 | }); 30 | console.log('unfolded.map:createMap(): map loaded!'); 31 | } 32 | }); 33 | } 34 | catch (error) { 35 | console.error('unfolded.map:createMap(): Error:\n', error); 36 | } 37 | map.render(mapContainer); 38 | return map; 39 | } 40 | -------------------------------------------------------------------------------- /src/test/checkNoTestProvider.ts: -------------------------------------------------------------------------------- 1 | // This script checks that the test provider isn't included in the package.json 2 | // or extension.ts. The extension provider is given as a tool for development, 3 | // but should not be published to the marketplace. 4 | // 5 | // This script is not super comprehensive, it's just here to prevent simple mistakes. 6 | 7 | import * as ts from 'typescript'; 8 | import * as path from 'path'; 9 | import { readFileSync, existsSync, writeFileSync } from 'fs'; 10 | import { EOL } from 'os'; 11 | 12 | const rootDir = path.resolve(__dirname, '..', '..'); 13 | const packageJson = require('../../package.json'); 14 | 15 | class DetectedError extends Error { 16 | constructor(message: string, public readonly fix: () => void) { 17 | super(message); 18 | } 19 | } 20 | 21 | const checkNotInExtensionTs = () => { 22 | const entrypoint = path.resolve(rootDir, 'src', 'extension', 'extension.ts'); 23 | if (!existsSync(entrypoint)) { 24 | return; 25 | } 26 | 27 | const contents = readFileSync(entrypoint, 'utf-8'); 28 | const program = ts.createSourceFile( 29 | path.basename(entrypoint), 30 | contents, 31 | ts.ScriptTarget.ESNext, 32 | true, 33 | ); 34 | 35 | const removeRegistration = (node: ts.Node) => () => writeFileSync( 36 | entrypoint, 37 | contents.slice(0, node.pos) + contents.slice(node.end + +(contents[node.end] === ',')), 38 | ); 39 | 40 | ts.forEachChild(program, function walk(node: ts.Node) { 41 | if ( 42 | ts.isCallExpression(node) && 43 | /(^|\W)registerNotebookContentProvider$/.test(node.expression.getText()) && 44 | node.arguments[1]?.getText().includes('SampleContentProvider') 45 | ) { 46 | throw new DetectedError( 47 | '`registerNotebookContentProvider()` is still called with the SampleContentProvider.', 48 | removeRegistration(node), 49 | ); 50 | } 51 | 52 | if ( 53 | ts.isCallExpression(node) && 54 | /(^|\W)registerNotebookKernel$/.test(node.expression.getText()) && 55 | node.arguments[2]?.getText().includes('SampleKernel') 56 | ) { 57 | throw new DetectedError( 58 | '`registerNotebookKernel()` is still called with the TestKernel.', 59 | removeRegistration(node), 60 | ); 61 | } 62 | 63 | ts.forEachChild(node, walk); 64 | }); 65 | }; 66 | 67 | const checkNotInPackageJson = () => { 68 | const providers = packageJson.contributes?.notebookProvider ?? []; 69 | const testIndex = providers.findIndex( 70 | (p: { viewType: string }) => p.viewType === 'test-notebook-renderer', 71 | ); 72 | if (testIndex !== -1) { 73 | throw new DetectedError( 74 | `The "test-notebook-renderer" is still registered in the contributes section of your package.json.`, 75 | () => { 76 | providers.splice(testIndex, 1); 77 | writeFileSync( 78 | path.resolve(rootDir, 'package.json'), 79 | JSON.stringify(packageJson, null, 2) + EOL, 80 | ); 81 | }, 82 | ); 83 | } 84 | }; 85 | (() => { 86 | if (process.argv.includes('--fix')) { 87 | while (true) { 88 | try { 89 | checkNotInPackageJson(); 90 | checkNotInExtensionTs(); 91 | } catch (e) { 92 | if (!(e instanceof DetectedError)) { 93 | throw e; 94 | } else { 95 | e.fix(); 96 | continue; 97 | } 98 | } 99 | 100 | return console.log('Test provider removed!'); 101 | } 102 | } 103 | 104 | let errors: DetectedError[] = []; 105 | for (const check of [checkNotInPackageJson, checkNotInExtensionTs]) { 106 | try { 107 | check(); 108 | } catch (e) { 109 | if (!(e instanceof DetectedError)) { 110 | throw e; 111 | } 112 | 113 | errors.push(e); 114 | } 115 | } 116 | 117 | 118 | if (!errors.length) { 119 | return; 120 | } 121 | 122 | const execPath = path.relative(process.cwd(), __filename); 123 | console.error(errors.map((e) => e.message).join(' ')); 124 | console.error(''); 125 | console.error( 126 | 'You should remove the test provider before publishing your extension to avoid ' + 127 | `conflicts. To fix this automatically, run \`node ${execPath} --fix\``, 128 | ); 129 | })(); 130 | -------------------------------------------------------------------------------- /src/test/runTest.ts: -------------------------------------------------------------------------------- 1 | import * as path from 'path'; 2 | 3 | import { runTests } from 'vscode-test'; 4 | 5 | async function main() { 6 | try { 7 | // The folder containing the Extension Manifest package.json 8 | // Passed to `--extensionDevelopmentPath` 9 | const extensionDevelopmentPath = path.resolve(__dirname, '../../'); 10 | 11 | // The path to test runner 12 | // Passed to --extensionTestsPath 13 | const extensionTestsPath = path.resolve(__dirname, './suite/index'); 14 | 15 | // Download VS Code, unzip it and run the integration test 16 | await runTests({ extensionDevelopmentPath, extensionTestsPath }); 17 | } catch (err) { 18 | console.error('Failed to run tests'); 19 | process.exit(1); 20 | } 21 | } 22 | 23 | main(); 24 | -------------------------------------------------------------------------------- /src/test/suite/extension.test.ts: -------------------------------------------------------------------------------- 1 | import * as assert from 'assert'; 2 | 3 | // You can import and use all API from the 'vscode' module 4 | // as well as import your extension to test it 5 | import * as vscode from 'vscode'; 6 | // import * as myExtension from '../extension'; 7 | 8 | suite('Extension Test Suite', () => { 9 | vscode.window.showInformationMessage('Start all tests.'); 10 | 11 | test('Sample test', () => { 12 | assert.strictEqual(-1, [1, 2, 3].indexOf(5)); 13 | assert.strictEqual(-1, [1, 2, 3].indexOf(0)); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /src/test/suite/index.ts: -------------------------------------------------------------------------------- 1 | import * as path from 'path'; 2 | import * as Mocha from 'mocha'; 3 | import * as glob from 'glob'; 4 | 5 | export function run(): Promise { 6 | // Create the mocha test 7 | const mocha = new Mocha({ 8 | ui: 'tdd', 9 | }); 10 | 11 | const testsRoot = path.resolve(__dirname, '..'); 12 | 13 | return new Promise((c, e) => { 14 | glob('**/**.test.js', { cwd: testsRoot }, (err, files) => { 15 | if (err) { 16 | return e(err); 17 | } 18 | 19 | // Add files to the test suite 20 | files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); 21 | 22 | try { 23 | // Run the mocha test 24 | mocha.run(failures => { 25 | if (failures > 0) { 26 | e(new Error(`${failures} tests failed.`)); 27 | } else { 28 | c(); 29 | } 30 | }); 31 | } catch (err) { 32 | console.error(err); 33 | e(err); 34 | } 35 | }); 36 | }); 37 | } 38 | -------------------------------------------------------------------------------- /src/test/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig-base.json", 3 | "compilerOptions": { 4 | "rootDir": ".", 5 | "outDir": "../../out/test", 6 | }, 7 | "references": [] 8 | } 9 | -------------------------------------------------------------------------------- /src/tsconfig-base.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "ES2019", 5 | "lib": [ 6 | "ES2019" 7 | ], 8 | "types": ["node"], 9 | "moduleResolution": "node", 10 | "sourceMap": true, 11 | "skipLibCheck": true, 12 | "strict": true /* enable all strict type-checking options */ 13 | /* Additional Checks */ 14 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ 15 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ 16 | // "noUnusedParameters": true, /* Report errors on unused parameters. */ 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "references": [ 4 | { 5 | "path": "./src/renderer" 6 | }, 7 | { 8 | "path": "./src/test" 9 | }, 10 | { 11 | "path": "./src/extension" 12 | } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/naming-convention */ 2 | const path = require('path'); 3 | 4 | const outputFilename = 'index.js'; 5 | const devServerPort = 8111; 6 | 7 | module.exports = (env, argv) => ({ 8 | mode: argv.mode, 9 | devtool: 'source-map', // argv.mode === 'production' ? false : 'inline-source-map', 10 | entry: './src/renderer/index.ts', 11 | output: { 12 | path: path.join(__dirname, 'out', 'renderer'), 13 | filename: outputFilename, 14 | publicPath: '', 15 | libraryTarget: 'module', 16 | }, 17 | resolve: { 18 | extensions: ['.ts', '.tsx', '.js', '.jsx', '.css'], 19 | }, 20 | experiments: { 21 | outputModule: true, 22 | }, 23 | module: { 24 | rules: [ 25 | { 26 | test: /\.tsx?$/, 27 | loader: 'ts-loader', 28 | options: { 29 | configFile: 'src/renderer/tsconfig.json', 30 | transpileOnly: true, 31 | compilerOptions: { 32 | noEmit: false, 33 | }, 34 | } 35 | }, 36 | { 37 | test: /\.css$/, 38 | use: [ 39 | 'style-loader', 40 | 'css-loader' 41 | ], 42 | }, 43 | { 44 | test: /\.svg$/, 45 | loader: 'svg-inline-loader', 46 | }, 47 | ], 48 | }, 49 | devServer: { 50 | port: devServerPort, 51 | hot: true, 52 | disableHostCheck: true, 53 | writeToDisk: true, 54 | headers: { 'Access-Control-Allow-Origin': '*' }, 55 | }, 56 | }); 57 | --------------------------------------------------------------------------------