├── src ├── components │ ├── Home │ │ ├── Home.styl │ │ └── index.js │ ├── PigeonMaps │ │ ├── PigeonMaps.styl │ │ └── index.js │ ├── ReactLeaflet │ │ ├── ReactLeafletMap.styl │ │ └── index.js │ ├── GoogleMapReactComponent │ │ ├── style.styl │ │ └── index.js │ ├── Header │ │ ├── Header.styl │ │ └── index.js │ ├── ReactMapGL │ │ └── index.js │ └── ReactMapGLDeckGL │ │ └── index.js ├── styles │ ├── globals.styl │ ├── media.styl │ └── main.styl ├── index.html ├── helper │ └── utils.js └── index.js ├── webpack ├── polyfills.js └── webpack.config.dev.js ├── config_sample.json ├── .gitignore ├── .babelrc ├── .eslintrc ├── README.md └── package.json /src/components/Home/Home.styl: -------------------------------------------------------------------------------- 1 | .menu 2 | font-size: 1rem 3 | -------------------------------------------------------------------------------- /src/components/PigeonMaps/PigeonMaps.styl: -------------------------------------------------------------------------------- 1 | .pigeonmaps 2 | color: black 3 | -------------------------------------------------------------------------------- /webpack/polyfills.js: -------------------------------------------------------------------------------- 1 | import 'babel-polyfill'; 2 | import 'whatwg-fetch'; 3 | -------------------------------------------------------------------------------- /src/components/ReactLeaflet/ReactLeafletMap.styl: -------------------------------------------------------------------------------- 1 | .map__reactleaflet 2 | flex: 1 0 3 | -------------------------------------------------------------------------------- /config_sample.json: -------------------------------------------------------------------------------- 1 | { 2 | "MAPBOX_ACCESS_TOKEN": "MapboxAccessToken", 3 | "GOOGLE_MAPS_API_KEY": "GoogleMapsApiKey" 4 | } 5 | -------------------------------------------------------------------------------- /src/components/GoogleMapReactComponent/style.styl: -------------------------------------------------------------------------------- 1 | .custom-marker 2 | background-color: #fff 3 | padding: 5px 4 | min-width: 100px 5 | -------------------------------------------------------------------------------- /src/styles/globals.styl: -------------------------------------------------------------------------------- 1 | // fonts 2 | $sansSerif = 'Source Sans Pro', sans-serif 3 | 4 | /* variables */ 5 | $lightgrey = #999 6 | $linkColor = #555 7 | $grey = #777 8 | $black = #222 9 | $white = #FFF 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # dependencies 2 | node_modules 3 | 4 | # production 5 | build 6 | bundle.zip 7 | 8 | # misc 9 | .DS_Store 10 | 11 | npm-debug.log 12 | yarn-error.log 13 | yarn.lock 14 | .yarnclean 15 | 16 | .vscode 17 | 18 | config.json 19 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "react-app", 4 | "es2015" 5 | ], 6 | "plugins": [ 7 | "transform-class-properties" 8 | ], 9 | "env": { 10 | "production": { 11 | "presets": ["react-optimize"] 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/styles/media.styl: -------------------------------------------------------------------------------- 1 | $tabletWidth = 768px 2 | $desktopWidth = 1024px 3 | 4 | @media screen and (min-width: $tabletWidth) 5 | body, html 6 | font-size: 12px 7 | 8 | @media screen and (min-width: $desktopWidth) 9 | body, html 10 | font-size: 14px 11 | -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Making Maps With React 8 | 9 | 10 |
11 | 12 | 13 | -------------------------------------------------------------------------------- /src/components/Header/Header.styl: -------------------------------------------------------------------------------- 1 | .header 2 | font-size: 1.6em 3 | background: #4889FF 4 | color: white 5 | padding: .5em 6 | font-weight: 700 7 | 8 | .header__claim 9 | display: flex 10 | align-items: center 11 | color: white 12 | text-decoration: none 13 | 14 | svg 15 | font-size: 2rem 16 | 17 | .header__title 18 | margin-left: .5rem 19 | display: inline-block 20 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "babel-eslint", 3 | "extends": ["airbnb"], 4 | "rules": { 5 | "react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }], 6 | "comma-dangle": ["error", { 7 | "objects": "never", 8 | "arrays": "never", 9 | "functions": "ignore", 10 | } 11 | ], 12 | "react/prop-types": 0, 13 | "no-console": 0, 14 | "react/prefer-stateless-function": [0, { "ignorePureComponents": true }], 15 | }, 16 | "env": { 17 | "browser": true 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/components/Header/index.js: -------------------------------------------------------------------------------- 1 | import React, { PureComponent } from 'react'; 2 | import { Link } from 'react-router-dom'; 3 | import GlobeIcon from 'react-icons/lib/go/globe'; 4 | 5 | import './Header.styl'; 6 | 7 | class Home extends PureComponent { 8 | 9 | render() { 10 | return ( 11 |
12 | 13 | 14 | Making Maps With Reacts 15 | 16 |
17 | ); 18 | } 19 | } 20 | 21 | export default Home; 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Making maps with react 2 | 3 | Overview of React mapping libraries. You can find the [regarding article](https://blog.webkid.io/making-maps-with-react) on our blog. 4 | 5 | ## Installation 6 | 7 | Install dependencies: 8 | 9 | ```sh 10 | $ yarn 11 | ``` 12 | 13 | otherwise 14 | 15 | ```sh 16 | $ npm install 17 | ``` 18 | ## Setup 19 | 20 | Rename config_sample.json to config.json and add your api keys for mapbox and googlemaps. 21 | 22 | ## Check out the maps 23 | 24 | Builds the application and starts a webserver with hot loading. 25 | Runs on [localhost:3000](http://localhost:3000/) 26 | 27 | ```sh 28 | $ npm start 29 | ``` 30 | -------------------------------------------------------------------------------- /src/styles/main.styl: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css?family=Source\+Sans\+Pro:400,600,700,900') 2 | @import '../../node_modules/leaflet/dist/leaflet.css'; 3 | 4 | @import 'media' 5 | @import 'globals' 6 | 7 | html, 8 | button, 9 | input, 10 | select, 11 | textarea 12 | color: $black 13 | 14 | body 15 | font-family: $sansSerif 16 | -webkit-font-smoothing: antialiased 17 | color: $black 18 | font-size: 10px 19 | line-height: 1.4 20 | 21 | body, 22 | html 23 | padding: 0 24 | margin: 0 25 | height:100% 26 | 27 | .app 28 | height: 100% 29 | display: flex 30 | flex-direction: column 31 | 32 | .map 33 | flex: 1 0 34 | display: flex 35 | position: relative 36 | 37 | #root 38 | height:100% 39 | -------------------------------------------------------------------------------- /src/components/Home/index.js: -------------------------------------------------------------------------------- 1 | import React, { PureComponent } from 'react'; 2 | import { Link } from 'react-router-dom'; 3 | 4 | import { slugify } from '../../helper/utils'; 5 | 6 | import './Home.styl'; 7 | 8 | const libraries = ['React Leaflet', 'Pigeon Maps', 'Google Map React', 'React Map GL', 'React MapGL with DeckGL']; 9 | 10 | class Home extends PureComponent { 11 | 12 | render() { 13 | return ( 14 |
15 | 23 |
24 | ); 25 | } 26 | } 27 | 28 | export default Home; 29 | -------------------------------------------------------------------------------- /src/helper/utils.js: -------------------------------------------------------------------------------- 1 | import turfRandom from '@turf/random'; 2 | import Immutable from 'immutable'; 3 | 4 | export function slugify(str) { 5 | return str.toLowerCase().replace(/\s/g, '-'); 6 | } 7 | 8 | export const markers = [ 9 | { 10 | name: 'Kottbusser Tor', 11 | latlng: [52.499040, 13.418392] 12 | }, { 13 | name: 'Görlitzer Park', 14 | latlng: [52.496912, 13.436738] 15 | }, { 16 | name: 'webkid', 17 | latlng: [52.501106, 13.422061] 18 | } 19 | ]; 20 | 21 | export const mapConfig = { 22 | center: [52.499219, 13.425416], 23 | zoom: 8 24 | }; 25 | 26 | const points = turfRandom('points', 50000, { bbox: [13.0535, 52.3303, 13.7262, 52.6675] }); 27 | export const locations = Immutable.fromJS(points.features.map(feat => feat.geometry.coordinates)); 28 | 29 | 30 | export const scatterPlotData = points.features.map(feat => ( 31 | { position: feat.geometry.coordinates, 32 | radius: 1, 33 | color: [255, 0, 0] 34 | } 35 | )); 36 | 37 | export function getColor(d) { 38 | const z = d.start[2]; 39 | const r = z / 10000; 40 | 41 | return [255 * ((1 - r) * 2), 128 * r, 255 * r, 255 * (1 - r)]; 42 | } 43 | -------------------------------------------------------------------------------- /src/components/GoogleMapReactComponent/index.js: -------------------------------------------------------------------------------- 1 | import React, { PureComponent } from 'react'; 2 | import GoogleMapReact from 'google-map-react'; 3 | import CONFIG from '../../../config.json'; 4 | import { markers, mapConfig } from '../../helper/utils'; 5 | 6 | import './style.styl'; 7 | 8 | const CustomMarker = ({ text }) =>

{text}

; 9 | 10 | class GoogleMapReactComponent extends PureComponent { 11 | render() { 12 | const GoogleMapsMarkers = markers.map(marker => ( 13 | 19 | )); 20 | 21 | return ( 22 | 31 | {GoogleMapsMarkers} 32 | 33 | ); 34 | } 35 | } 36 | 37 | export default GoogleMapReactComponent; 38 | -------------------------------------------------------------------------------- /src/components/PigeonMaps/index.js: -------------------------------------------------------------------------------- 1 | /*eslint-disable */ 2 | 3 | import React, { PureComponent } from 'react'; 4 | import Map from 'pigeon-maps'; 5 | import Marker from 'pigeon-marker'; 6 | import { markers, mapConfig } from '../../helper/utils'; 7 | 8 | import './PigeonMaps.styl'; 9 | 10 | const getProvider = (x, y, z) => `https://cartodb-basemaps-a.global.ssl.fastly.net/light_all/${z}/${x}/${y}.png`; 11 | 12 | class PigeonMaps extends PureComponent { 13 | 14 | onMarkerClick(evt) { 15 | console.log(evt.payload); 16 | } 17 | 18 | render() { 19 | // create an array with marker components 20 | const PigeonMarkers = markers.map(marker => ( 21 | 22 | )); 23 | 24 | return ( 25 |
26 | 33 | {PigeonMarkers} 34 | 35 |
36 | ); 37 | } 38 | } 39 | 40 | export default PigeonMaps; 41 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import { BrowserRouter, Route } from 'react-router-dom'; 4 | 5 | import 'normalize.css'; 6 | 7 | import Header from './components/Header'; 8 | import Home from './components/Home'; 9 | import ReactLeafletMap from './components/ReactLeaflet'; 10 | import PigeonMaps from './components/PigeonMaps'; 11 | import GoogleMapReactComponent from './components/GoogleMapReactComponent'; 12 | 13 | import ReactMapGL from './components/ReactMapGL'; 14 | import ReactMapGLDeckGL from './components/ReactMapGLDeckGL'; 15 | 16 | import './styles/main.styl'; 17 | 18 | ReactDOM.render( 19 | 20 |
21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 |
, 30 | document.getElementById('root') 31 | ); 32 | -------------------------------------------------------------------------------- /src/components/ReactMapGL/index.js: -------------------------------------------------------------------------------- 1 | import React, { PureComponent } from 'react'; 2 | import MapGL, { ScatterplotOverlay } from 'react-map-gl'; 3 | import CONFIG from '../../../config.json'; 4 | import { mapConfig, locations } from '../../helper/utils'; 5 | 6 | class ReactMapGL extends PureComponent { 7 | constructor(props) { 8 | super(props); 9 | 10 | this.state = { 11 | viewport: { 12 | width: window.innerWidth, 13 | height: 600, 14 | latitude: mapConfig.center[0], 15 | longitude: mapConfig.center[1], 16 | zoom: mapConfig.zoom, 17 | isDragging: false, 18 | startDragLngLat: mapConfig.center, 19 | pitch: 50, 20 | bearing: 0 21 | } 22 | }; 23 | 24 | this.onChangeViewport = this.onChangeViewport.bind(this); 25 | } 26 | 27 | onChangeViewport(viewport) { 28 | this.setState({ 29 | viewport: { ...this.state.viewport, ...viewport } 30 | }); 31 | } 32 | 33 | render() { 34 | const { viewport } = this.state; 35 | return ( 36 |
37 | 43 | 52 | 53 |
54 | ); 55 | } 56 | } 57 | 58 | export default ReactMapGL; 59 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "making-maps-with-react", 3 | "version": "1.0.0", 4 | "description": "lightweight react starterkit with webpack, redux, react-router", 5 | "scripts": { 6 | "start": "NODE_ENV=development webpack-dev-server --config webpack/webpack.config.dev.js --watch --colors --no-info" 7 | }, 8 | "repository": { 9 | "url": "git@github.com:wbkd/making-maps-with-react.git", 10 | "type": "git" 11 | }, 12 | "author": "webkid.io", 13 | "license": "MIT", 14 | "devDependencies": { 15 | "babel-core": "^6.21.0", 16 | "babel-eslint": "^7.1.1", 17 | "babel-loader": "^6.2.10", 18 | "babel-plugin-transform-class-properties": "^6.23.0", 19 | "babel-polyfill": "^6.23.0", 20 | "babel-preset-es2015": "^6.18.0", 21 | "babel-preset-react-app": "^2.0.1", 22 | "babel-preset-react-optimize": "^1.0.1", 23 | "copy-webpack-plugin": "^4.0.1", 24 | "eslint": "^3.13.1", 25 | "eslint-config-airbnb": "^14.1.0", 26 | "eslint-config-react-app": "^0.6.2", 27 | "eslint-loader": "^1.6.1", 28 | "eslint-plugin-import": "^2.2.0", 29 | "eslint-plugin-jsx-a11y": "^4.0.0", 30 | "eslint-plugin-react": "^6.9.0", 31 | "extract-text-webpack-plugin": "2.1.0", 32 | "html-webpack-plugin": "^2.26.0", 33 | "stylus": "^0.54.5", 34 | "stylus-loader": "^3.0.1", 35 | "webpack": "2.3.3", 36 | "webpack-dev-server": "2.4.2", 37 | "zip-webpack-plugin": "^1.1.0" 38 | }, 39 | "dependencies": { 40 | "@turf/random": "^4.1.0", 41 | "autoprefixer": "^6.6.1", 42 | "babel-polyfill": "^6.23.0", 43 | "css-loader": "^0.28.0", 44 | "d3-request": "^1.0.5", 45 | "deck.gl": "^4.0.5", 46 | "file-loader": "^0.11.1", 47 | "google-map-react": "^0.24.0", 48 | "immutable": "^3.8.1", 49 | "leaflet": "^1.0.3", 50 | "luma.gl": "^3.0.2", 51 | "normalize.css": "^6.0.0", 52 | "object-assign": "^4.1.0", 53 | "pigeon-maps": "^0.8.2", 54 | "pigeon-marker": "^0.3.2", 55 | "postcss-loader": "^1.2.2", 56 | "promise": "^7.1.1", 57 | "react": "^15.4.2", 58 | "react-dev-utils": "0.5.2", 59 | "react-dom": "^15.4.2", 60 | "react-icons": "^2.2.3", 61 | "react-leaflet": "^1.7.1", 62 | "react-map-gl": "^1.8.2", 63 | "react-redux": "^5.0.2", 64 | "react-router": "4.0.0", 65 | "react-router-dom": "4.0.0", 66 | "style-loader": "^0.16.1", 67 | "whatwg-fetch": "^2.0.1" 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /webpack/webpack.config.dev.js: -------------------------------------------------------------------------------- 1 | const Path = require('path'); 2 | const Autoprefixer = require('autoprefixer'); 3 | const Webpack = require('webpack'); 4 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 5 | const CopyWebpackPlugin = require('copy-webpack-plugin'); 6 | const WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin'); 7 | 8 | module.exports = { 9 | devtool: 'cheap-module-eval-source-map', 10 | devServer: 11 | { 12 | contentBase: './build', 13 | hot: true, 14 | compress: true, 15 | port: 3000, 16 | inline: true, 17 | publicPath: '/', 18 | historyApiFallback: true 19 | }, 20 | entry: [ 21 | require.resolve('./polyfills'), 22 | Path.resolve(__dirname, '../src/index.js') 23 | ], 24 | output: { 25 | path: Path.join(__dirname, '../build'), 26 | filename: 'js/bundle.js' 27 | }, 28 | plugins: [ 29 | new Webpack.LoaderOptionsPlugin({ 30 | options: { 31 | context: __dirname, 32 | eslint: { 33 | configFile: Path.resolve('./.eslintrc') 34 | }, 35 | postcss: [ 36 | Autoprefixer 37 | ] 38 | } 39 | }), 40 | new Webpack.DefinePlugin({ 41 | 'process.env': { 42 | NODE_ENV: JSON.stringify('development'), 43 | BASENAME: JSON.stringify('/') 44 | } 45 | }), 46 | new Webpack.HotModuleReplacementPlugin(), 47 | // This Webpack plugin ensures npm install forces a project rebuild. 48 | new WatchMissingNodeModulesPlugin(Path.resolve(__dirname, 'node_modules')), 49 | new HtmlWebpackPlugin({ 50 | inject: true, 51 | template: Path.resolve(__dirname, '../src/index.html'), 52 | basename: process.env.BASENAME 53 | }), 54 | // copy data folder to make it available in redux loadData action 55 | new CopyWebpackPlugin([ 56 | { from: Path.resolve(__dirname, '../src/public/data'), to: 'data' } 57 | ]) 58 | ], 59 | resolve: { 60 | alias: { 61 | 'mapbox-gl$': Path.resolve('./node_modules/mapbox-gl/dist/mapbox-gl.js') 62 | } 63 | }, 64 | module: { 65 | rules: [ 66 | { 67 | test: /\.styl$/i, 68 | enforce: 'pre', 69 | use: ['style-loader', 'css-loader', 'stylus-loader'] 70 | }, 71 | { 72 | test: /\.(js|jsx)$/, 73 | include: Path.resolve(__dirname, '../src'), 74 | exclude: /(node_modules|webpack)/, 75 | use: ['babel-loader', 'eslint-loader'] 76 | }, 77 | { 78 | test: /\.css$/, 79 | use: ['style-loader', 'css-loader'] 80 | }, 81 | { 82 | test: /\.(ico|jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2)(\?.*)?$/, 83 | use: { 84 | loader: 'file-loader', 85 | options: { 86 | name: 'assets/images/[name].[ext]' 87 | } 88 | } 89 | } 90 | ] 91 | } 92 | }; 93 | -------------------------------------------------------------------------------- /src/components/ReactMapGLDeckGL/index.js: -------------------------------------------------------------------------------- 1 | /*eslint-disable */ 2 | import React, { PureComponent } from 'react'; 3 | 4 | import MapGL from 'react-map-gl'; 5 | import DeckGL, { GeoJsonLayer, ScatterplotLayer, ScreenGridLayer } from 'deck.gl'; 6 | import { json as requestJson } from 'd3-request'; 7 | 8 | import CONFIG from '../../../config.json'; 9 | 10 | import { mapConfig, scatterPlotData, getColor } from '../../helper/utils'; 11 | 12 | class ReactMapGLDeckGL extends PureComponent { 13 | constructor(props) { 14 | super(props); 15 | 16 | this.state = { 17 | viewport: { 18 | width: window.innerWidth, 19 | height: 600, 20 | latitude: mapConfig.center[0], 21 | longitude: mapConfig.center[1], 22 | zoom: mapConfig.zoom, 23 | isDragging: false, 24 | startDragLngLat: mapConfig.center, 25 | pitch: 50, 26 | bearing: 0 27 | }, 28 | geojson: null 29 | }; 30 | 31 | requestJson(`${process.env.BASENAME}data/berlin_bezirke.json`, (error, response) => { 32 | if (!error) { 33 | this.setState({ geojson: response }); 34 | } 35 | }); 36 | 37 | 38 | this.onChangeViewport = this.onChangeViewport.bind(this); 39 | } 40 | 41 | onChangeViewport(viewport) { 42 | this.setState({ 43 | viewport: { ...this.state.viewport, ...viewport } 44 | }); 45 | } 46 | 47 | initialize(gl) { 48 | gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE, gl.ONE_MINUS_DST_ALPHA, gl.ONE); 49 | gl.blendEquation(gl.FUNC_ADD); 50 | } 51 | 52 | render() { 53 | const { viewport, geojson } = this.state; 54 | 55 | // const scatterplotLayer = new ScatterplotLayer({ 56 | // id: 'scatter-plott-layer', 57 | // data: scatterPlotData, 58 | // radiusScale: 50, 59 | // outline: true, 60 | // getPosition: d => d.position 61 | // }); 62 | 63 | const geosjsonLayer = new GeoJsonLayer({ 64 | id: 'geojson-layer', 65 | data: geojson, 66 | filled: false, 67 | stroked: true, 68 | lineWidthMinPixels: 1, 69 | lineWidthScale: 1, 70 | getLineColor: d => [175, 175, 175] 71 | }); 72 | 73 | const screenGridLayer = new ScreenGridLayer({ 74 | id: 'screen-grid-layer', 75 | data: scatterPlotData, 76 | cellSizePixels: 10, 77 | minColor: [43, 140, 190, 0], 78 | maxColor: [43, 140, 190, 255] 79 | }); 80 | 81 | return ( 82 |
83 | 90 | 95 | 96 |
97 | ); 98 | } 99 | } 100 | 101 | export default ReactMapGLDeckGL; 102 | -------------------------------------------------------------------------------- /src/components/ReactLeaflet/index.js: -------------------------------------------------------------------------------- 1 | import React, { PureComponent } from 'react'; 2 | import Leaflet from 'leaflet'; 3 | import { Map, Marker, Popup, TileLayer, GeoJSON } from 'react-leaflet'; 4 | import { markers, mapConfig } from '../../helper/utils'; 5 | 6 | import './ReactLeafletMap.styl'; 7 | 8 | Leaflet.Icon.Default.imagePath = '//cdnjs.cloudflare.com/ajax/libs/leaflet/1.0.0/images/'; 9 | 10 | 11 | // Data for GeoJSON usage 12 | const data = { 13 | type: "FeatureCollection", 14 | features: [ 15 | { 16 | type: "Feature", 17 | id: "01", 18 | properties: { name: "Alabama", density: 94.65 }, 19 | geometry: { 20 | type: "Polygon", 21 | coordinates: [ 22 | [ 23 | [-87.359296, 35.00118], 24 | [-85.606675, 34.984749], 25 | [-85.431413, 34.124869], 26 | [-85.184951, 32.859696], 27 | [-85.069935, 32.580372], 28 | [-84.960397, 32.421541], 29 | [-85.004212, 32.322956], 30 | [-84.889196, 32.262709], 31 | [-85.058981, 32.13674], 32 | [-85.053504, 32.01077], 33 | [-85.141136, 31.840985], 34 | [-85.042551, 31.539753], 35 | [-85.113751, 31.27686], 36 | [-85.004212, 31.003013], 37 | [-85.497137, 30.997536], 38 | [-87.600282, 30.997536], 39 | [-87.633143, 30.86609], 40 | [-87.408589, 30.674397], 41 | [-87.446927, 30.510088], 42 | [-87.37025, 30.427934], 43 | [-87.518128, 30.280057], 44 | [-87.655051, 30.247195], 45 | [-87.90699, 30.411504], 46 | [-87.934375, 30.657966], 47 | [-88.011052, 30.685351], 48 | [-88.10416, 30.499135], 49 | [-88.137022, 30.318396], 50 | [-88.394438, 30.367688], 51 | [-88.471115, 31.895754], 52 | [-88.241084, 33.796253], 53 | [-88.098683, 34.891641], 54 | [-88.202745, 34.995703], 55 | [-87.359296, 35.00118] 56 | ] 57 | ] 58 | } 59 | } 60 | ] 61 | } 62 | 63 | class ReactLeafletMap extends PureComponent { 64 | 65 | 66 | // Get the style for your polygons from GeoJSON, it can be dependable on a parameter you want. 67 | // For example, you can use different style for different density of the location 68 | getStyle(feature) { 69 | return { 70 | fillColor: #ece7f2, 71 | weight: 2, 72 | opacity: 1, 73 | color: 'blue', 74 | dashArray: '3', 75 | fillOpacity: 0.7 76 | } 77 | } 78 | 79 | render() { 80 | // create an array with marker components 81 | const LeafletMarkers = markers.map(marker => ( 82 | 83 | 84 | {marker.name} 85 | 86 | 87 | )); 88 | 89 | return ( 90 |
91 | 92 | 96 | {LeafletMarkers} 97 | {/* You can now try to find Alabama on a Map to see how it looks like now with GeoJSON*/} 98 | 99 | 100 |
101 | ); 102 | } 103 | } 104 | 105 | export default ReactLeafletMap; 106 | --------------------------------------------------------------------------------