Saturday, 4 August 2018

react google map

project site: http://chuanshuoge1-react-map.surge.sh/


marker cluster, menu opened


direction api, menu collapse


fusion layer, toggle sub menu
--src
  --app.js
  --app.css
  --index.js
  --category
    --bicyclingLayer.js
    --directionsRenderer.js
    --key.js
    --markerCluster.js
    --singleMarker.js
--package.json

package.json

{
  "name": "react-map",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "antd": "^3.7.3",
    "react": "^16.4.1",
    "react-dom": "^16.4.1",
    "react-google-maps": "^9.4.5",
    "react-router-dom": "^4.3.1",
    "react-scripts": "1.1.4"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  }
}

------------------------------------------------

public/index.html 

add  <script src="https://maps.googleapis.com/maps/api/js"></script>

------------------------------------------------

src/index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
import { BrowserRouter } from 'react-router-dom'

ReactDOM.render(<BrowserRouter><App /></BrowserRouter>, document.getElementById('root'));
registerServiceWorker();

---------------------------------------------------------

app.js

import React, { Component } from 'react';
import './App.css';
import { Switch, Route, Link } from 'react-router-dom';

import SingleMarker from './category/singleMarker';
import MarkerCluster from './category/markerCluster';
import BicyclingLayer from './category/bicyclingLayer';
import DirectionRenderer from './category/directionsRenderer';
import MapWithAFusionTablesLayer from './category/fusionLayer';
import MapWithADrawingManager from './category/drawingManager';
import ControlledZoom from './category/controlledZoom';
import MapWithGroundOverlay from './category/groundOverlay';
import Kml from './category/kmlLayer';
import MapWithASearchBox from './category/searchBox';

import 'antd/dist/antd.css';
import { Row, Col, Menu, Icon, Button } from 'antd';

const SubMenu = Menu.SubMenu;

class App extends Component {
    constructor(props) {
        super(props);

        this.state = {
            menuCollapse: false,
            menuGrid: 6,
            mapGrid: 18,
        };
    }

    handleClickCollapse() {
        this.state.menuCollapse ?
            this.setState({
                menuCollapse: false,
                menuGrid: 6,
                mapGrid: 18,
            }) :
            this.setState({
                menuCollapse: true,
                menuGrid: 2,
                mapGrid: 22,
            })
    }

    render() {

        return (
            <div>
                <Row>
                    <Col span={this.state.menuGrid}>
                        <Button type="primary" size='large' type="dashed"
                            className='collapseButton'
                            onClick={() => this.handleClickCollapse()}>
                            <h2>
                                {this.state.menuCollapse ? null : 'Gooogle Map'}
                                <Icon type={this.state.menuCollapse ? 'double-right' : 'double-left'} />
                            </h2>
                        </Button>

                        <Menu
                            defaultSelectedKeys={['2']}
                            defaultOpenKeys={['sub1']}
                            mode="inline"
                            inlineCollapsed={this.state.menuCollapse}
                        >
                            <SubMenu key="sub1" title={<span><Icon type="pushpin-o" /><span>Marker</span></span>}>

                                <Menu.Item key="1"><Link to='/singleMarker' className="my-link-color">Single Marker</Link></Menu.Item>
                                <Menu.Item key="2"><Link to='/markerCluster' className="my-link-color">Marker Cluster</Link></Menu.Item>                             
                            </SubMenu>

                            <SubMenu key="sub2" title={<span><Icon type="switcher" /><span>Layer</span></span>}>

                                <Menu.Item key="3"><Link to='/bicycleLayer' className="my-link-color">Bicycling Layer</Link></Menu.Item>                             
                                <Menu.Item key="5"><Link to='/fusionLayer' className="my-link-color">Fusion Layer</Link></Menu.Item>                               
                                <Menu.Item key="8"><Link to='/groundOverlay' className="my-link-color">Ground Overlay</Link></Menu.Item>
                                <Menu.Item key="9"><Link to='/kmlLayer' className="my-link-color">Kml Layer</Link></Menu.Item>                             
                            </SubMenu>

                            <SubMenu key="sub3" title={<span><Icon type="tool" /><span>Control</span></span>}>

                                <Menu.Item key="4"><Link to='/directionRenderer' className="my-link-color">Direction renderer</Link></Menu.Item>
                                <Menu.Item key="6"><Link to='/drawingManager' className="my-link-color">Drawing Manager</Link></Menu.Item>
                                <Menu.Item key="7"><Link to='/controlledZoom' className="my-link-color">Controlled Zoom</Link></Menu.Item>
                                <Menu.Item key="10"><Link to='/searchBox' className="my-link-color">Search Box</Link></Menu.Item>
                            </SubMenu>
                        </Menu>
                    </Col>
                    <Col span={this.state.mapGrid}>
                        <Switch>
                            <Route exact path='/' component={MarkerCluster} />
                            <Route path='/singleMarker' component={SingleMarker} />
                            <Route path='/markerCluster' component={MarkerCluster} />
                            <Route path='/bicycleLayer' component={BicyclingLayer} />
                            <Route path='/directionRenderer' component={DirectionRenderer} />
                            <Route path='/fusionLayer' component={MapWithAFusionTablesLayer} />
                            <Route path='/drawingManager' component={MapWithADrawingManager} />
                            <Route path='/controlledZoom' component={ControlledZoom} />
                            <Route path='/groundOverlay' component={MapWithGroundOverlay} />
                            <Route path='/kmlLayer' component={Kml} />
                            <Route path='/searchBox' component={MapWithASearchBox} />
                        </Switch>
                    </Col>
                </Row>


            </div>
        );
    }
}

export default App;

-------------------------------------------------

app.css

.my-link-color {
    color: white;
    text-decoration: none;
}

    .my-link-color:hover {
        color: cyan;
        text-decoration: none;
    }

.my-link-color:focus {
    color: gold;
    text-decoration: none;
}

.my-infoBox{
    background-color:gold;
    width:50px;
}

.collapseButton{
    width:100%;
}
---------------------------------------------

category/key.js

const apiKey1 = 'AIzaSyCBNpYVkcXG8TYxFwI4oymTaSFaHrsLULc';
const apiKey2 = 'AIzaSyBfWxcbSfG6xZE4J7adQwjbskYgl64-Cvc';
const apiKey3 = 'AIzaSyBrKRs5NQL0dBEb1oJNK_K96jkN71N0GT4';
const apiKey4 = 'AIzaSyDRrz98hmiLfSoCXNNm2jcVc1e1wTENAhA';

const googleUrl = {
    url1: "https://maps.googleapis.com/maps/api/js?key=" + apiKey1 + "&v=3.exp&libraries=geometry,drawing,places",
    url2: "https://maps.googleapis.com/maps/api/js?key=" + apiKey2 + "&v=3.exp&libraries=geometry,drawing,places",
    url3: "https://maps.googleapis.com/maps/api/js?key=" + apiKey3 + "&v=3.exp&libraries=geometry,drawing,places",
    url4: "https://maps.googleapis.com/maps/api/js?key=" + apiKey4 + "&v=3.exp&libraries=geometry,drawing,places",
}

export default googleUrl;

-------------------------------------------

category/singleMarker.js


import React, { Component } from 'react';
import '../App.css';
import googleUrl from './key';

import { Icon } from 'antd';

import { compose, withProps, withStateHandlers } from "recompose";
import {
    withScriptjs,
    withGoogleMap,
    GoogleMap,
    Marker,
} from "react-google-maps";
import { InfoBox } from "react-google-maps/lib/components/addons/InfoBox";

class SingleMarker extends Component {
    constructor(props) {
        super(props);

        this.state = {
            infoBoxOpen: true,
        };
    }


    handleMarkerClick = () => {
        this.setState(prevState => { return { infoBoxOpen: !prevState.infoBoxOpen } })
    }

    render() {
        const MyMap = compose(
            withProps({
                googleMapURL: googleUrl.url1,
                loadingElement: <div style={{ height: `100%` }} />,
                containerElement: <div style={{ height: `400px` }} />,
                mapElement: <div style={{ height: `100%` }} />,
                center: { lat: -34.397, lng: 150.644 },
            }),
            withScriptjs,
            withGoogleMap
        )(props =>
            <GoogleMap
                defaultZoom={5}
                defaultCenter={props.center}
            >

                <Marker position={props.center}
                    draggable={true}
                    onClick={() => this.handleMarkerClick()} >

                    {this.state.infoBoxOpen &&
                        <InfoBox>
                        <h1 className='my-infoBox'> <Icon type="info-circle-o"/>abc</h1>                     
                        </InfoBox>
                    }
                </Marker>}
            </GoogleMap>
            );

        return (
            <MyMap />
        );
    }
}

export default SingleMarker;

---------------------------------------------------------

markerCluster.js

import React, { Component } from 'react';
import '../App.css';
import googleUrl from './key';

import { withScriptjs, withGoogleMap, GoogleMap, Marker } from "react-google-maps";
import { compose, withProps, withHandlers } from "recompose";
import { MarkerClusterer } from "react-google-maps/lib/components/addons/MarkerClusterer";
import fetch from "isomorphic-fetch";

class MarkerCluster extends Component {
    constructor(props) {
        super(props);

        this.state = {
            markers: [],
        };
    }

    componentDidMount() {
        const url = [
            // Length issue
            `https://gist.githubusercontent.com`,
            `/farrrr/dfda7dd7fccfec5474d3`,
            `/raw/758852bbc1979f6c4522ab4e92d1c92cba8fb0dc/data.json`
        ].join("")

        fetch(url)
            .then(res => res.json())
            .then(data => {
                this.setState({ markers: data.photos });
            });
    }

    render() {

        const MyMapComponent = compose(
            withProps({
                googleMapURL: googleUrl.url1,
                loadingElement: <div style={{ height: `100%` }} />,
                containerElement: <div style={{ height: `400px` }} />,
                mapElement: <div style={{ height: `100%` }} />,
            }),
            withHandlers({
                onMarkerClustererClick: () => (markerClusterer) => {
                    const clickedMarkers = markerClusterer.getMarkers()
                    console.log(`Current clicked markers length: ${clickedMarkers.length}`)
                    console.log(clickedMarkers)
                }
            }),
            withScriptjs,
            withGoogleMap
        )((props) =>
            <GoogleMap
                defaultZoom={1}
                defaultCenter={{ lat: 25.0391667, lng: 121.525 }}
            >

                {/***cluster****/}

                <MarkerClusterer
                    onClick={props.onMarkerClustererClick}
                    averageCenter
                    enableRetinaIcons
                    gridSize={60}
                >
                    {this.state.markers.map(marker => (
                        <Marker
                            key={marker.photo_id}
                            position={{ lat: marker.latitude, lng: marker.longitude }}
                        />
                    ))}
                </MarkerClusterer>
            </GoogleMap>
            )

        return (
            <MyMapComponent />
        );
    }
}

export default MarkerCluster;

----------------------------------------------------

bicyclingLayer.js

import React, { Component } from 'react';
import '../App.css';
import googleUrl from './key';

import { compose, withProps, withStateHandlers } from "recompose";
import {
    withScriptjs,
    withGoogleMap,
    GoogleMap,
    BicyclingLayer,
} from "react-google-maps";

class BikeLayer extends Component {
    constructor(props) {
        super(props);

        this.state = {
       
        };
    }

    render() {
        const MyMap = compose(
            withProps({
                googleMapURL: googleUrl.url1,
                loadingElement: <div style={{ height: `100%` }} />,
                containerElement: <div style={{ height: `400px` }} />,
                mapElement: <div style={{ height: `100%` }} />,
            }),
            withScriptjs,
            withGoogleMap
        )(props =>
            <GoogleMap
                defaultZoom={12}
                defaultCenter={{ lat: 34.17223, lng: -118.37897 }}
            >

                <BicyclingLayer autoUpdate />
            </GoogleMap>
            );

        return (
            <MyMap />
        );
    }
}

export default BikeLayer;

---------------------------------------------------

import React, { Component } from 'react';
import '../App.css';
import googleUrl from './key';

import { compose, withProps, lifecycle } from "recompose";
import {
    withScriptjs,
    withGoogleMap,
    GoogleMap,
    DirectionsRenderer,
} from "react-google-maps";

const google = window.google

class Direction extends Component {
    constructor(props) {
        super(props);

        this.state = {
        };
    }

    render() {

        const MyMap = compose(
            withProps({
                googleMapURL: googleUrl.url3,
                loadingElement: <div style={{ height: `100%` }} />,
                containerElement: <div style={{ height: `400px` }} />,
                mapElement: <div style={{ height: `100%` }} />,
            }),
            withScriptjs,
            withGoogleMap,
            lifecycle({
                componentDidMount() {
                    const DirectionsService = new google.maps.DirectionsService();

                    DirectionsService.route({
                        origin: new google.maps.LatLng(41, -87),
                        destination: new google.maps.LatLng(42, -88),
                        travelMode: google.maps.TravelMode.DRIVING,
                    }, (result, status) => {
                        if (status === google.maps.DirectionsStatus.OK) {
                            this.setState({
                                directions: result,
                            });
                        } else {
                            console.error(`error fetching directions ${result}`);
                        }
                    });
                }
            })
        )(props =>
            <GoogleMap
                defaultZoom={7}
                defaultCenter={{ lat: 41.8507300, lng: -87.6512600 }}
            >

                {props.directions && <DirectionsRenderer directions={props.directions} />}
            </GoogleMap>
            );

        return (
            <div>
              may have exceeded daily request limits
            <MyMap />
            </div>
        );
    }
}

export default Direction;

----------------------------------------------------

reference:

1 comment:

  1. Smm Smart Market .I recently found many useful information in your website especially this blog page. Among the lots of comments on your articles. Thanks for sharing. Buy Google Maps Reviews

    ReplyDelete