├── .gitignore ├── README.md ├── package.json ├── public ├── favicon.ico ├── index.html ├── logo192.png ├── logo512.png ├── manifest.json └── robots.txt ├── src ├── App.css ├── App.js ├── assets │ ├── data.json │ └── img │ │ └── icon.svg ├── components │ ├── Home.js │ ├── IconLocation.js │ ├── MapView.js │ ├── MarkerPopup.js │ └── Markers.js ├── index.css └── index.js └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # Snowpack dependency directory (https://snowpack.dev/) 45 | web_modules/ 46 | 47 | # TypeScript cache 48 | *.tsbuildinfo 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Microbundle cache 57 | .rpt2_cache/ 58 | .rts2_cache_cjs/ 59 | .rts2_cache_es/ 60 | .rts2_cache_umd/ 61 | 62 | # Optional REPL history 63 | .node_repl_history 64 | 65 | # Output of 'npm pack' 66 | *.tgz 67 | 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | 71 | # dotenv environment variables file 72 | .env 73 | .env.test 74 | 75 | # parcel-bundler cache (https://parceljs.org/) 76 | .cache 77 | .parcel-cache 78 | 79 | # Next.js build output 80 | .next 81 | out 82 | 83 | # Nuxt.js build / generate output 84 | .nuxt 85 | dist 86 | 87 | # Gatsby files 88 | .cache/ 89 | # Comment in the public line in if your project uses Gatsby and not Next.js 90 | # https://nextjs.org/blog/next-9-1#public-directory-support 91 | # public 92 | 93 | # vuepress build output 94 | .vuepress/dist 95 | 96 | # Serverless directories 97 | .serverless/ 98 | 99 | # FuseBox cache 100 | .fusebox/ 101 | 102 | # DynamoDB Local files 103 | .dynamodb/ 104 | 105 | # TernJS port file 106 | .tern-port 107 | 108 | # Stores VSCode versions used for testing VSCode extensions 109 | .vscode-test 110 | 111 | # yarn v2 112 | .yarn/cache 113 | .yarn/unplugged 114 | .yarn/build-state.yml 115 | .yarn/install-state.gz 116 | .pnp.* 117 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # REACT-MAP-LEAFLET (GEO-Location) 2 | 3 | ## Description 4 | 5 | This repository is a Software of Application with React,NodeJS,Leaflet,etc 6 | 7 | ## Installation 8 | 9 | Using NodeJS, React preferably. 10 | 11 | ## Plugins 12 | 13 | React Leaflet 14 | 15 | 16 | ## Usage 17 | 18 | ```html 19 | $ git clone https://github.com/DanielArturoAlejoAlvarez/react-map-leaflet-geolocation[NAME APP] 20 | 21 | $ npm install 22 | 23 | $ yarn install 24 | 25 | ``` 26 | 27 | Follow the following steps and you're good to go! Important: 28 | 29 | ![alt text](https://images.ctfassets.net/3prze68gbwl1/asset-17suaysk1qa1i6h/e51ffc6222fb6517db3b1fefd4870337/687474703a2f2f692e696d6775722e636f6d2f645657766f58562e676966.gif) 30 | 31 | ## Coding 32 | 33 | ### Components 34 | ```js 35 | ... 36 | export const IconLocation = L.icon({ 37 | iconUrl: require('../assets/img/icon.svg'), 38 | iconRetinaUrl: require('../assets/img/icon.svg'), 39 | iconAnchor: null, 40 | shadowUrl: null, 41 | shadowSize: null, 42 | shadowAnchor: null, 43 | iconSize: [35,35], 44 | className: 'leaflet-venue-icon' 45 | }); 46 | 47 | const MarkerPopup = (props)=>{ 48 | const { name } = props.data 49 | 50 | return ( 51 | 52 |
{name}
53 |
54 | ) 55 | 56 | } 57 | 58 | const Markers = (props) => { 59 | 60 | 61 | const { places } = props 62 | 63 | const markers = places.map((place,index)=>( 64 | 69 | 70 | 71 | )) 72 | 73 | 74 | return ( 75 |
76 | {markers} 77 |
78 | ) 79 | } 80 | 81 | const MapView = (props) => { 82 | 83 | const [state,setState] = useState({ 84 | currentLocation: { 85 | lat: 52.500772, 86 | lng: 13.472764 87 | }, 88 | zoom: 13, 89 | data 90 | }) 91 | 92 | const location = useLocation() 93 | const history = useHistory() 94 | 95 | useEffect(() => { 96 | if (location.state.latitude && location.state.longitude) { 97 | const currentLocation = { 98 | lat: location.state.latitude, 99 | lng: location.state.longitude 100 | } 101 | setState({ 102 | ...state, 103 | currentLocation 104 | }) 105 | 106 | history.replace({ 107 | pathname: '/map-view', 108 | state: {} 109 | }) 110 | } 111 | 112 | }, [location]) 113 | 114 | return ( 115 |
116 | 117 | 121 | 122 | 123 |
124 | ) 125 | } 126 | 127 | function App() { 128 | return ( 129 | 130 | 131 | 132 | 133 | ; 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | ); 142 | } 143 | ... 144 | ``` 145 | 146 | 147 | 148 | ## Contributing 149 | 150 | Bug reports and pull requests are welcome on GitHub at https://github.com/DanielArturoAlejoAlvarez/react-map-leaflet-geolocation. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct. 151 | 152 | ## License 153 | 154 | The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT). 155 | 156 | ``` 157 | 158 | ``` -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-map", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^4.2.4", 7 | "@testing-library/react": "^9.3.2", 8 | "@testing-library/user-event": "^7.1.2", 9 | "leaflet": "^1.6.0", 10 | "react": "^16.13.1", 11 | "react-dom": "^16.13.1", 12 | "react-leaflet": "^2.7.0", 13 | "react-router-dom": "^5.2.0", 14 | "react-scripts": "3.4.3" 15 | }, 16 | "scripts": { 17 | "start": "react-scripts start", 18 | "build": "react-scripts build", 19 | "test": "react-scripts test", 20 | "eject": "react-scripts eject" 21 | }, 22 | "eslintConfig": { 23 | "extends": "react-app" 24 | }, 25 | "browserslist": { 26 | "production": [ 27 | ">0.2%", 28 | "not dead", 29 | "not op_mini all" 30 | ], 31 | "development": [ 32 | "last 1 chrome version", 33 | "last 1 firefox version", 34 | "last 1 safari version" 35 | ] 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanielArturoAlejoAlvarez/react-map-leaflet-geolocation/4620bee768eab70834fe418e115c046de9fcbd8b/public/favicon.ico -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | React App 28 | 29 | 30 | 31 |
32 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanielArturoAlejoAlvarez/react-map-leaflet-geolocation/4620bee768eab70834fe418e115c046de9fcbd8b/public/logo192.png -------------------------------------------------------------------------------- /public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanielArturoAlejoAlvarez/react-map-leaflet-geolocation/4620bee768eab70834fe418e115c046de9fcbd8b/public/logo512.png -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /src/App.css: -------------------------------------------------------------------------------- 1 | .leaflet-container { 2 | width: 100vw; 3 | height: 100vh; 4 | } 5 | 6 | .item-place { 7 | font-weight: 600; 8 | background-color: gray; 9 | color: white; 10 | margin-right: .2rem; 11 | padding: .2rem .5rem; 12 | border-radius: 5px; 13 | } -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { BrowserRouter as Router, Switch, Route } from 'react-router-dom' 3 | import MapView from "./components/MapView"; 4 | import './App.css' 5 | import Home from "./components/Home"; 6 | 7 | function App() { 8 | return ( 9 | 10 | 11 | 12 | 13 | ; 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | ); 22 | } 23 | 24 | export default App; 25 | -------------------------------------------------------------------------------- /src/assets/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "places": [ 3 | { 4 | "description": "Schon seit längerem wollte Rummel sich sein kleines Paradies schaffen, hat tiefe stille Wasser betörnt und stürmischen Zeiten getrotzt und hat endlich geankert - in einer schönen kleinen Bucht nicht weit von Euch! In diese Bucht läd Rummel von Mai bis Mitte September zum Chillen und Grillen, zum Schunkeln, Munkeln und natürlich Trunkeln. Und wenn Rummel mal so richtig gut drauf ist, dann wird auch mal ordentlich gerummelt! So oder so, zu Wasser wie zur Bucht, auch der Rummel ist nichts ohne seine Crew. Also Leichtmatrosen und Matrösinnen - kommt rum und lasst es Euch gut gehn! Ahoi* Ach ja, geöffnet ist nur an sonnigen und regenfreien Tagen :) ________________ Reservierungsanfragen sind nur per Mail möglich bucht@rummels-welt.de (Reservierungsanfragen werden nur zwischen Di-Fr beantwortet) ", 5 | "name": "Rummels Bucht", 6 | "geometry": [ 7 | 52.500772, 8 | 13.472764 9 | ] 10 | }, 11 | { 12 | "description": "Das SEZ bietet ein großes Sport-, Freizeit- und Erholungsangebot. Ab sofort könnt ihr das SEZ für Events unter: sez@glut.berlin anmieten. Kommt vorbei und genießt den industriellen Charm einer in Vergessenheit geglaubten Location. ", 13 | "name": "SEZ Berlin", 14 | "geometry": [ 15 | 52.527025, 16 | 13.446139 17 | ] 18 | }, 19 | { 20 | "description": "Das Huxleys seit fast einem Jahrhundert ein Name in Berlin. Varietébühne, Sportpalast, Rollschuhbahn und Ausflugsziel am Rande des Volksparks Hasenheide. Das HUXLEYS hat eine lange Geschichte, und die ist verbunden mit Entertainment, Vergnügen und Livemusik.", 21 | "name": "Huxley's Neue Welt", 22 | "geometry": [ 23 | 52.486319, 24 | 13.421437 25 | ] 26 | }, 27 | { 28 | "description": "Wir sind ein Veranstaltungsort. Eine Plattform. Wir sind ein Kollektiv. Basisdemokratisch und solidarisch. Wir sind das Mensch Meier. Und ihr seid es auch, wenn ihr da seid. Wir wollen einen Raum erschaffen, in dem wir unsere Beziehungen selbstbestimmt formen. Das ist im Kapitalismus, im Patriarchat, leider kein erreichbares Ziel. Aber wir haben einfach schon mal angefangen, uns dieses Ziel als Weg formuliert. Für unsere Zukunft. In einem Raum für Inspiration, Intervention und Bewegung. KulturKunstPartyPolitik. Mit den Mitteln der Kritik und den Waffen der Kunst unordentlich Theater machen. Mensch Meier ", 29 | "name": "Mensch Meier", 30 | "geometry": [ 31 | 52.535069, 32 | 13.452312 33 | ] 34 | }, 35 | { 36 | "description": "The club is located in a former underground gay cruising toilet under the Yorckstrasse in Kreuzberg.", 37 | "name": "Zur Klappe", 38 | "geometry": [ 39 | 52.493039, 40 | 13.387248 41 | ] 42 | }, 43 | { 44 | "description": "Formerly Shift Bar in the Kraftwerk complex which also houses Tresor.", 45 | "name": "OHM", 46 | "geometry": [ 47 | 52.510507, 48 | 13.42022 49 | ] 50 | }, 51 | { 52 | "description": "Club for electronic Music directly in the heart of Berlin! Between Hakescher Markt and 1 min. away from S Alexanderplatz. Stylish Crowd and many of Berlins most known artists.", 53 | "name": "M-BIA", 54 | "geometry": [ 55 | 52.522437, 56 | 13.409063 57 | ] 58 | }, 59 | { 60 | "description": "Booze, Karaoke and Rock'n'Roll! Sparkles, disco lights, 14 private karaoke cabins and a big stage waiting for your performance! We have 10 cabins for walk-ins (for up to 10 guests) and 4 larger cabins for larger groups, which can be reserved in advance (for up to 18 guests). Mondays - MultiSEXual BOXhopping! Queer + Friends. Mix + Mingle! Box Sharing + Caring! 3,- Entry. Sing in the karaoke boxes all night long! Big stage opens at 22h. Tuesdays - The House of Presents’ Drag Show Doors at 9, pre-show at 10, main show at 11 Wednesdays - BOX HAPPY HOUR All cabins half-priced from 7pm - midnight Thursdays - Mixed Bag! Special Events, DJs, Live Musik, Queer Events, and more! Fridays / Saturday / Sunday: SING ON STAGE!", 61 | "name": "Monster Ronson's Ichiban Karaoke", 62 | "geometry": [ 63 | 52.505188, 64 | 13.448437 65 | ] 66 | }, 67 | { 68 | "description": "Ägyptisches & Arabisches Restaurant · Smoker's Lounge · Club · Café · Cocktail Bar · Der feine Orient in Berlin", 69 | "name": "Marooush Restaurant - Lounge - Bar - Club", 70 | "geometry": [ 71 | 52.500938, 72 | 13.321438 73 | ] 74 | }, 75 | { 76 | "description": "Kater Blau gives you everything you need for a party: House, Techno, Konfetti. Chill next to the Spree. All this on the ex wood markt area.", 77 | "name": "Kater Blau", 78 | "geometry": [ 79 | 52.512187, 80 | 13.425563 81 | ] 82 | } 83 | ] 84 | } -------------------------------------------------------------------------------- /src/assets/img/icon.svg: -------------------------------------------------------------------------------- 1 | 2 | orange pin 3 | 4 | 5 | 6 | 7 | 8 | 9 | Layer 1 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/components/Home.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from 'react' 2 | import { Link } from 'react-router-dom' 3 | 4 | const Home = () => { 5 | 6 | const [state, setState] = useState({ 7 | longitude: 0, 8 | latitude: 0 9 | }) 10 | 11 | useEffect(() => { 12 | navigator.geolocation.getCurrentPosition( 13 | function(position){ 14 | //console.log(position) 15 | setState({ 16 | longitude: position.coords.longitude, 17 | latitude: position.coords.latitude 18 | }) 19 | }, 20 | function(error) { 21 | console.log(error) 22 | }, 23 | { 24 | enableHighAccuracy: true 25 | } 26 | )}, []) 27 | 28 | return ( 29 |
30 |

GEO-Location

31 |

Latitude: {state.latitude}

32 |

Longitude: {state.longitude}

33 | See my Geolocation 37 |
38 | ) 39 | } 40 | 41 | export default Home 42 | -------------------------------------------------------------------------------- /src/components/IconLocation.js: -------------------------------------------------------------------------------- 1 | import L from 'leaflet' 2 | 3 | export const IconLocation = L.icon({ 4 | iconUrl: require('../assets/img/icon.svg'), 5 | iconRetinaUrl: require('../assets/img/icon.svg'), 6 | iconAnchor: null, 7 | shadowUrl: null, 8 | shadowSize: null, 9 | shadowAnchor: null, 10 | iconSize: [35,35], 11 | className: 'leaflet-venue-icon' 12 | }); -------------------------------------------------------------------------------- /src/components/MapView.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from 'react' 2 | import { Map, TileLayer } from 'react-leaflet' 3 | import 'leaflet/dist/leaflet.css' 4 | import Markers from './Markers' 5 | 6 | import data from '../assets/data.json' 7 | import { useLocation, useHistory } from 'react-router-dom' 8 | 9 | 10 | const MapView = (props) => { 11 | 12 | 13 | 14 | const [state,setState] = useState({ 15 | currentLocation: { 16 | lat: 52.500772, 17 | lng: 13.472764 18 | }, 19 | zoom: 13, 20 | data 21 | }) 22 | 23 | const location = useLocation() 24 | const history = useHistory() 25 | 26 | useEffect(() => { 27 | if (location.state.latitude && location.state.longitude) { 28 | const currentLocation = { 29 | lat: location.state.latitude, 30 | lng: location.state.longitude 31 | } 32 | setState({ 33 | ...state, 34 | currentLocation 35 | }) 36 | 37 | history.replace({ 38 | pathname: '/map-view', 39 | state: {} 40 | }) 41 | } 42 | 43 | }, [location]) 44 | 45 | return ( 46 |
47 | 48 | 52 | 53 | 54 |
55 | ) 56 | } 57 | 58 | export default MapView 59 | -------------------------------------------------------------------------------- /src/components/MarkerPopup.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Popup } from 'react-leaflet' 3 | 4 | const MarkerPopup = (props)=>{ 5 | const { name } = props.data 6 | 7 | return ( 8 | 9 |
{name}
10 |
11 | ) 12 | 13 | } 14 | 15 | export default MarkerPopup -------------------------------------------------------------------------------- /src/components/Markers.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { IconLocation } from './IconLocation' 3 | 4 | import { Marker } from 'react-leaflet'; 5 | import MarkerPopup from './MarkerPopup'; 6 | 7 | const Markers = (props) => { 8 | 9 | 10 | const { places } = props 11 | 12 | const markers = places.map((place,index)=>( 13 | 18 | 19 | 20 | )) 21 | 22 | 23 | return ( 24 |
25 | {markers} 26 |
27 | ) 28 | } 29 | 30 | export default Markers 31 | -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import App from './App'; 5 | 6 | 7 | ReactDOM.render( 8 | 9 | 10 | , 11 | document.getElementById('root') 12 | ); 13 | --------------------------------------------------------------------------------