[v7] Update examples (#1659)

This commit is contained in:
Xiaoji Chen 2022-01-02 14:12:15 -08:00 committed by Xiaoji Chen
parent a488f36296
commit 55ce87d3f7
87 changed files with 926 additions and 920 deletions

View File

@ -1,24 +0,0 @@
body {
margin: 0;
background: #000;
}
#map {
width: 100vw;
height: 100vh;
}
.control-panel {
position: absolute;
top: 0;
right: 0;
max-width: 320px;
background: #fff;
box-shadow: 0 2px 4px rgba(0,0,0,0.3);
padding: 12px 24px;
margin: 20px;
font-size: 13px;
line-height: 2;
color: #6b6b76;
text-transform: uppercase;
outline: none;
}

View File

@ -3,7 +3,32 @@
<head>
<meta charset='UTF-8' />
<title>react-map-gl Example</title>
<link rel="stylesheet" type="text/css" href="app.css" />
<link href="https://api.mapbox.com/mapbox-gl-js/v2.6.1/mapbox-gl.css" rel="stylesheet">
<style>
body {
margin: 0;
font-family: Helvetica, Arial, sans-serif;
}
#map {
width: 100vw;
height: 100vh;
}
.control-panel {
position: absolute;
top: 0;
right: 0;
max-width: 320px;
background: #fff;
box-shadow: 0 2px 4px rgba(0,0,0,0.3);
padding: 12px 24px;
margin: 20px;
font-size: 13px;
line-height: 2;
color: #6b6b76;
text-transform: uppercase;
outline: none;
}
</style>
</head>
<body>
<div id="map"></div>

View File

@ -1,21 +1,23 @@
{
"scripts": {
"start": "webpack-dev-server --progress --hot --open",
"start-local": "webpack-dev-server --env.local --progress --hot --open"
"start-local": "webpack-dev-server --env local --progress --hot --open"
},
"dependencies": {
"react": "^16.3.0",
"react-dom": "^16.3.0",
"react-map-gl": "^6.0.0"
"react": "^17.0.0",
"react-dom": "^17.0.0",
"react-map-gl": "^7.0.0",
"mapbox-gl": "^2.0.0"
},
"devDependencies": {
"@babel/core": "^7.0.0",
"@babel/plugin-proposal-class-properties": "^7.0.0",
"@babel/preset-env": "^7.0.0",
"@babel/preset-react": "^7.0.0",
"babel-loader": "^8.0.0",
"webpack": "^4.20.0",
"webpack-cli": "^3.1.2",
"webpack-dev-server": "^3.1.0"
"ts-loader": "^9.0.0",
"typescript": "^4.0.0",
"webpack": "^5.65.0",
"webpack-cli": "^4.9.0",
"webpack-dev-server": "^4.7.0"
}
}

View File

@ -1,53 +1,49 @@
import * as React from 'react';
import {useState, useRef} from 'react';
import {useRef} from 'react';
import {render} from 'react-dom';
import MapGL, {Source, Layer} from 'react-map-gl';
import {Map, Source, Layer} from 'react-map-gl';
import ControlPanel from './control-panel';
import {clusterLayer, clusterCountLayer, unclusteredPointLayer} from './layers';
import type {MapRef} from 'react-map-gl';
import type {GeoJSONSource} from 'react-map-gl';
const MAPBOX_TOKEN = ''; // Set your mapbox token here
export default function App() {
const [viewport, setViewport] = useState({
latitude: 40.67,
longitude: -103.59,
zoom: 3,
bearing: 0,
pitch: 0
});
const mapRef = useRef(null);
const mapRef = useRef<MapRef>(null);
const onClick = event => {
const feature = event.features[0];
const clusterId = feature.properties.cluster_id;
const mapboxSource = mapRef.current.getMap().getSource('earthquakes');
const map = mapRef.current.getMap();
const mapboxSource = map.getSource('earthquakes') as GeoJSONSource;
mapboxSource.getClusterExpansionZoom(clusterId, (err, zoom) => {
if (err) {
return;
}
setViewport({
...viewport,
longitude: feature.geometry.coordinates[0],
latitude: feature.geometry.coordinates[1],
map.easeTo({
center: feature.geometry.coordinates,
zoom,
transitionDuration: 500
duration: 500
});
});
};
return (
<>
<MapGL
{...viewport}
width="100%"
height="100%"
<Map
initialViewState={{
latitude: 40.67,
longitude: -103.59,
zoom: 3
}}
mapStyle="mapbox://styles/mapbox/dark-v9"
onViewportChange={setViewport}
mapboxApiAccessToken={MAPBOX_TOKEN}
mapboxAccessToken={MAPBOX_TOKEN}
interactiveLayerIds={[clusterLayer.id]}
onClick={onClick}
ref={mapRef}
@ -64,7 +60,7 @@ export default function App() {
<Layer {...clusterCountLayer} />
<Layer {...unclusteredPointLayer} />
</Source>
</MapGL>
</Map>
<ControlPanel />
</>
);

View File

@ -1,4 +1,6 @@
export const clusterLayer = {
import type {LayerProps} from 'react-map-gl';
export const clusterLayer: LayerProps = {
id: 'clusters',
type: 'circle',
source: 'earthquakes',
@ -9,7 +11,7 @@ export const clusterLayer = {
}
};
export const clusterCountLayer = {
export const clusterCountLayer: LayerProps = {
id: 'cluster-count',
type: 'symbol',
source: 'earthquakes',
@ -21,7 +23,7 @@ export const clusterCountLayer = {
}
};
export const unclusteredPointLayer = {
export const unclusteredPointLayer: LayerProps = {
id: 'unclustered-point',
type: 'circle',
source: 'earthquakes',

View File

@ -0,0 +1,10 @@
{
"compilerOptions": {
"target": "es2020",
"jsx": "react",
"allowSyntheticDefaultImports": true,
"resolveJsonModule": true,
"moduleResolution": "node",
"sourceMap": true
}
}

View File

@ -5,33 +5,40 @@
const resolve = require('path').resolve;
const webpack = require('webpack');
const BABEL_CONFIG = {
presets: ['@babel/env', '@babel/react'],
plugins: ['@babel/proposal-class-properties']
};
const config = {
mode: 'development',
devServer: {
static: '.'
},
entry: {
app: resolve('./src/app.js')
app: resolve('./src/app')
},
output: {
library: 'App'
},
resolve: {
extensions: ['.ts', '.tsx', '.js', '.json']
},
module: {
rules: [
{
// Compile ES2015 using babel
test: /\.js$/,
test: /\.(ts|js)x?$/,
include: [resolve('.')],
exclude: [/node_modules/],
use: [
{
loader: 'babel-loader',
options: BABEL_CONFIG
options: {
presets: ['@babel/env', '@babel/react']
}
},
{
loader: 'ts-loader'
}
]
}
@ -39,7 +46,7 @@ const config = {
},
// Optional: Enables reading mapbox token from environment variable
plugins: [new webpack.EnvironmentPlugin(['MapboxAccessToken'])]
plugins: [new webpack.EnvironmentPlugin({MapboxAccessToken: ''})]
};
// Enables bundling against src in this repo rather than the installed version

View File

@ -1,22 +1,23 @@
import * as React from 'react';
export default function Pin({onClick}) {
return (
<svg
height={20}
viewBox="0 0 24 24"
style={{
cursor: 'pointer',
fill: '#d00',
stroke: 'none'
}}
onClick={onClick}
>
<path
d="M20.2,15.7L20.2,15.7c1.1-1.6,1.8-3.6,1.8-5.7c0-5.6-4.5-10-10-10S2,4.5,2,10c0,2,0.6,3.9,1.6,5.4c0,0.1,0.1,0.2,0.2,0.3
const ICON = `M20.2,15.7L20.2,15.7c1.1-1.6,1.8-3.6,1.8-5.7c0-5.6-4.5-10-10-10S2,4.5,2,10c0,2,0.6,3.9,1.6,5.4c0,0.1,0.1,0.2,0.2,0.3
c0,0,0.1,0.1,0.1,0.2c0.2,0.3,0.4,0.6,0.7,0.9c2.6,3.1,7.4,7.6,7.4,7.6s4.8-4.5,7.4-7.5c0.2-0.3,0.5-0.6,0.7-0.9
C20.1,15.8,20.2,15.8,20.2,15.7z"
/>
C20.1,15.8,20.2,15.8,20.2,15.7z`;
const pinStyle = {
cursor: 'pointer',
fill: '#d00',
stroke: 'none'
};
function Pin(props) {
const {size = 20} = props;
return (
<svg height={size} viewBox="0 0 24 24" style={pinStyle}>
<path d={ICON} />
</svg>
);
}
export default React.memo(Pin);

View File

@ -2,7 +2,7 @@
import * as React from 'react';
import {useState, useCallback} from 'react';
import {render} from 'react-dom';
import Map, {Style} from 'react-map-gl';
import Map, {MapboxStyle} from 'react-map-gl';
import ControlPanel from './control-panel';
import MAP_STYLE from '../../map-style-basic-v8.json';
@ -39,7 +39,7 @@ export default function App() {
<>
<Map
initialViewState={initialViewState}
mapStyle={MAP_STYLE as Style}
mapStyle={MAP_STYLE as MapboxStyle}
onClick={onClick}
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}

View File

@ -1,24 +0,0 @@
body {
margin: 0;
background: #000;
}
#map {
width: 100vw;
height: 100vh;
}
.control-panel {
position: absolute;
top: 0;
right: 0;
max-width: 320px;
background: #fff;
box-shadow: 0 2px 4px rgba(0,0,0,0.3);
padding: 12px 24px;
margin: 20px;
font-size: 13px;
line-height: 2;
color: #6b6b76;
text-transform: uppercase;
outline: none;
}

View File

@ -3,7 +3,33 @@
<head>
<meta charset='UTF-8' />
<title>react-map-gl Example</title>
<link rel="stylesheet" type="text/css" href="app.css" />
<link href="https://api.mapbox.com/mapbox-gl-js/v2.6.1/mapbox-gl.css" rel="stylesheet">
<style>
body {
margin: 0;
font-family: Helvetica, Arial, sans-serif;
}
#map {
width: 100vw;
height: 100vh;
}
.control-panel {
position: absolute;
top: 0;
right: 0;
max-width: 320px;
background: #fff;
box-shadow: 0 2px 4px rgba(0,0,0,0.3);
padding: 12px 24px;
margin: 20px;
font-size: 13px;
line-height: 2;
color: #6b6b76;
text-transform: uppercase;
outline: none;
}
</style>
</head>
<body>
<div id="map"></div>

View File

@ -1,21 +1,23 @@
{
"scripts": {
"start": "webpack-dev-server --progress --hot --open",
"start-local": "webpack-dev-server --env.local --progress --hot --open"
"start-local": "webpack-dev-server --env local --progress --hot --open"
},
"dependencies": {
"react": "^16.3.0",
"react-dom": "^16.3.0",
"react-map-gl": "^6.0.0"
"mapbox-gl": "^2.0.0",
"react": "^17.0.0",
"react-dom": "^17.0.0",
"react-map-gl": "^7.0.0"
},
"devDependencies": {
"@babel/core": "^7.0.0",
"@babel/plugin-proposal-class-properties": "^7.0.0",
"@babel/preset-env": "^7.0.0",
"@babel/preset-react": "^7.0.0",
"babel-loader": "^8.0.0",
"webpack": "^4.20.0",
"webpack-cli": "^3.1.2",
"webpack-dev-server": "^3.1.0"
"ts-loader": "^9.0.0",
"typescript": "^4.0.0",
"webpack": "^5.65.0",
"webpack-cli": "^4.9.0",
"webpack-dev-server": "^4.7.0"
}
}

View File

@ -1,65 +1,56 @@
import * as React from 'react';
import {useState, useCallback} from 'react';
import {render} from 'react-dom';
import MapGL, {Marker, NavigationControl} from 'react-map-gl';
import Map, {Marker, NavigationControl} from 'react-map-gl';
import ControlPanel from './control-panel';
import Pin from './pin';
import type {MarkerDragEvent, LngLat} from 'react-map-gl';
const TOKEN = ''; // Set your mapbox token here
const navStyle = {
position: 'absolute',
top: 0,
left: 0,
padding: '10px'
const initialViewState = {
latitude: 40,
longitude: -100,
zoom: 3.5
};
export default function App() {
const [viewport, setViewport] = useState({
latitude: 40,
longitude: -100,
zoom: 3.5,
bearing: 0,
pitch: 0
});
const [marker, setMarker] = useState({
latitude: 40,
longitude: -100
});
const [events, logEvents] = useState({});
const [events, logEvents] = useState<Record<string, LngLat>>({});
const onMarkerDragStart = useCallback(event => {
const onMarkerDragStart = useCallback((event: MarkerDragEvent) => {
logEvents(_events => ({..._events, onDragStart: event.lngLat}));
}, []);
const onMarkerDrag = useCallback(event => {
const onMarkerDrag = useCallback((event: MarkerDragEvent) => {
logEvents(_events => ({..._events, onDrag: event.lngLat}));
setMarker({
longitude: event.lngLat.lng,
latitude: event.lngLat.lat
});
}, []);
const onMarkerDragEnd = useCallback(event => {
const onMarkerDragEnd = useCallback((event: MarkerDragEvent) => {
logEvents(_events => ({..._events, onDragEnd: event.lngLat}));
setMarker({
longitude: event.lngLat[0],
latitude: event.lngLat[1]
});
}, []);
return (
<>
<MapGL
{...viewport}
width="100%"
height="100%"
<Map
initialViewState={initialViewState}
mapStyle="mapbox://styles/mapbox/dark-v9"
onViewportChange={setViewport}
mapboxApiAccessToken={TOKEN}
mapboxAccessToken={TOKEN}
>
<Marker
longitude={marker.longitude}
latitude={marker.latitude}
offsetTop={-20}
offsetLeft={-10}
anchor="bottom"
draggable
onDragStart={onMarkerDragStart}
onDrag={onMarkerDrag}
@ -68,10 +59,8 @@ export default function App() {
<Pin size={20} />
</Marker>
<div className="nav" style={navStyle}>
<NavigationControl />
</div>
</MapGL>
<NavigationControl />
</Map>
<ControlPanel events={events} />
</>
);

View File

@ -1,4 +1,5 @@
import * as React from 'react';
import type {LngLat} from 'react-map-gl';
const eventNames = ['onDragStart', 'onDrag', 'onDragEnd'];
@ -6,7 +7,7 @@ function round5(value) {
return (Math.round(value * 1e5) / 1e5).toFixed(5);
}
function ControlPanel(props) {
function ControlPanel(props: {events: Record<string, LngLat>}) {
return (
<div className="control-panel">
<h3>Draggable Marker</h3>
@ -17,7 +18,8 @@ function ControlPanel(props) {
const lngLat = events[eventName];
return (
<div key={eventName}>
<strong>{eventName}:</strong> {lngLat ? lngLat.map(round5).join(', ') : <em>null</em>}
<strong>{eventName}:</strong>{' '}
{lngLat ? `${round5(lngLat.lng)}, ${round5(lngLat.lat)}` : <em>null</em>}
</div>
);
})}

View File

@ -0,0 +1,10 @@
{
"compilerOptions": {
"target": "es2020",
"jsx": "react",
"allowSyntheticDefaultImports": true,
"resolveJsonModule": true,
"moduleResolution": "node",
"sourceMap": true
}
}

View File

@ -5,33 +5,40 @@
const resolve = require('path').resolve;
const webpack = require('webpack');
const BABEL_CONFIG = {
presets: ['@babel/env', '@babel/react'],
plugins: ['@babel/proposal-class-properties']
};
const config = {
mode: 'development',
devServer: {
static: '.'
},
entry: {
app: resolve('./src/app.js')
app: resolve('./src/app')
},
output: {
library: 'App'
},
resolve: {
extensions: ['.ts', '.tsx', '.js', '.json']
},
module: {
rules: [
{
// Compile ES2015 using babel
test: /\.js$/,
test: /\.(ts|js)x?$/,
include: [resolve('.')],
exclude: [/node_modules/],
use: [
{
loader: 'babel-loader',
options: BABEL_CONFIG
options: {
presets: ['@babel/env', '@babel/react']
}
},
{
loader: 'ts-loader'
}
]
}
@ -39,7 +46,7 @@ const config = {
},
// Optional: Enables reading mapbox token from environment variable
plugins: [new webpack.EnvironmentPlugin(['MapboxAccessToken'])]
plugins: [new webpack.EnvironmentPlugin({MapboxAccessToken: ''})]
};
// Enables bundling against src in this repo rather than the installed version

View File

@ -1,29 +0,0 @@
body {
margin: 0;
font-family: Helvetica, Arial, sans-serif;
}
#map {
width: 100vw;
height: 100vh;
}
.county-info {
font-size: 12px;
font-weight: 700;
}
.control-panel {
position: absolute;
top: 0;
right: 0;
max-width: 320px;
background: #fff;
box-shadow: 0 2px 4px rgba(0,0,0,0.3);
padding: 12px 24px;
margin: 20px;
font-size: 13px;
line-height: 2;
color: #6b6b76;
text-transform: uppercase;
outline: none;
}

View File

@ -3,7 +3,38 @@
<head>
<meta charset='UTF-8' />
<title>react-map-gl Example</title>
<link rel="stylesheet" type="text/css" href="app.css" />
<link href="https://api.mapbox.com/mapbox-gl-js/v2.6.1/mapbox-gl.css" rel="stylesheet">
<style>
body {
margin: 0;
font-family: Helvetica, Arial, sans-serif;
}
#map {
width: 100vw;
height: 100vh;
}
.county-info {
font-size: 12px;
font-weight: 700;
}
.control-panel {
position: absolute;
top: 0;
right: 0;
max-width: 320px;
background: #fff;
box-shadow: 0 2px 4px rgba(0,0,0,0.3);
padding: 12px 24px;
margin: 20px;
font-size: 13px;
line-height: 2;
color: #6b6b76;
text-transform: uppercase;
outline: none;
}
</style>
</head>
<body>
<div id="map"></div>

View File

@ -1,21 +1,23 @@
{
"scripts": {
"start": "webpack-dev-server --progress --hot --open",
"start-local": "webpack-dev-server --env.local --progress --hot --open"
"start-local": "webpack-dev-server --env local --progress --hot --open"
},
"dependencies": {
"react": "^16.3.0",
"react-dom": "^16.3.0",
"react-map-gl": "^6.0.0"
"mapbox-gl": "^2.0.0",
"react": "^17.0.0",
"react-dom": "^17.0.0",
"react-map-gl": "^7.0.0"
},
"devDependencies": {
"@babel/core": "^7.0.0",
"@babel/plugin-proposal-class-properties": "^7.0.0",
"@babel/preset-env": "^7.0.0",
"@babel/preset-react": "^7.0.0",
"babel-loader": "^8.0.0",
"webpack": "^4.20.0",
"webpack-cli": "^3.1.2",
"webpack-dev-server": "^3.1.0"
"ts-loader": "^9.0.0",
"typescript": "^4.0.0",
"webpack": "^5.65.0",
"webpack-cli": "^4.9.0",
"webpack-dev-server": "^4.7.0"
}
}

View File

@ -1,29 +1,21 @@
import * as React from 'react';
import {useState, useMemo, useCallback} from 'react';
import {render} from 'react-dom';
import MapGL, {Popup, Source, Layer} from 'react-map-gl';
import Map, {Popup, Source, Layer} from 'react-map-gl';
import ControlPanel from './control-panel';
import {countiesLayer, highlightLayer} from './map-style.js';
import {countiesLayer, highlightLayer} from './map-style';
const MAPBOX_TOKEN = ''; // Set your mapbox token here
export default function App() {
const [viewport, setViewport] = useState({
latitude: 38.88,
longitude: -98,
zoom: 3,
minZoom: 2,
bearing: 0,
pitch: 0
});
const [hoverInfo, setHoverInfo] = useState(null);
const onHover = useCallback(event => {
const county = event.features && event.features[0];
setHoverInfo({
longitude: event.lngLat[0],
latitude: event.lngLat[1],
longitude: event.lngLat.lng,
latitude: event.lngLat.lat,
countyName: county && county.properties.COUNTY
});
}, []);
@ -33,14 +25,16 @@ export default function App() {
return (
<>
<MapGL
{...viewport}
width="100%"
height="100%"
<Map
initialViewState={{
latitude: 38.88,
longitude: -98,
zoom: 3
}}
minZoom={2}
mapStyle="mapbox://styles/mapbox/light-v9"
mapboxApiAccessToken={MAPBOX_TOKEN}
onViewportChange={setViewport}
onHover={onHover}
mapboxAccessToken={MAPBOX_TOKEN}
onMouseMove={onHover}
interactiveLayerIds={['counties']}
>
<Source type="vector" url="mapbox://mapbox.82pkq93d">
@ -51,13 +45,14 @@ export default function App() {
<Popup
longitude={hoverInfo.longitude}
latitude={hoverInfo.latitude}
offset={[0, -10]}
closeButton={false}
className="county-info"
>
{selectedCounty}
</Popup>
)}
</MapGL>
</Map>
<ControlPanel />
</>
);

View File

@ -1,4 +1,6 @@
export const countiesLayer = {
import type {FillLayer} from 'react-map-gl';
export const countiesLayer: FillLayer = {
id: 'counties',
type: 'fill',
'source-layer': 'original',
@ -8,7 +10,7 @@ export const countiesLayer = {
}
};
// Highlighted county polygons
export const highlightLayer = {
export const highlightLayer: FillLayer = {
id: 'counties-highlighted',
type: 'fill',
source: 'counties',

View File

@ -0,0 +1,10 @@
{
"compilerOptions": {
"target": "es2020",
"jsx": "react",
"allowSyntheticDefaultImports": true,
"resolveJsonModule": true,
"moduleResolution": "node",
"sourceMap": true
}
}

View File

@ -5,33 +5,40 @@
const resolve = require('path').resolve;
const webpack = require('webpack');
const BABEL_CONFIG = {
presets: ['@babel/env', '@babel/react'],
plugins: ['@babel/proposal-class-properties']
};
const config = {
mode: 'development',
devServer: {
static: '.'
},
entry: {
app: resolve('./src/app.js')
app: resolve('./src/app')
},
output: {
library: 'App'
},
resolve: {
extensions: ['.ts', '.tsx', '.js', '.json']
},
module: {
rules: [
{
// Compile ES2015 using babel
test: /\.js$/,
test: /\.(ts|js)x?$/,
include: [resolve('.')],
exclude: [/node_modules/],
use: [
{
loader: 'babel-loader',
options: BABEL_CONFIG
options: {
presets: ['@babel/env', '@babel/react']
}
},
{
loader: 'ts-loader'
}
]
}
@ -39,7 +46,7 @@ const config = {
},
// Optional: Enables reading mapbox token from environment variable
plugins: [new webpack.EnvironmentPlugin(['MapboxAccessToken'])]
plugins: [new webpack.EnvironmentPlugin({MapboxAccessToken: ''})]
};
// Enables bundling against src in this repo rather than the installed version

View File

@ -1,24 +0,0 @@
body {
margin: 0;
background: #000;
}
#map {
width: 100vw;
height: 100vh;
}
.control-panel {
position: absolute;
top: 0;
right: 0;
max-width: 320px;
background: #fff;
box-shadow: 0 2px 4px rgba(0,0,0,0.3);
padding: 12px 24px;
margin: 20px;
font-size: 13px;
line-height: 2;
color: #6b6b76;
text-transform: uppercase;
outline: none;
}

View File

@ -3,7 +3,32 @@
<head>
<meta charset='UTF-8' />
<title>react-map-gl Example</title>
<link rel="stylesheet" type="text/css" href="app.css" />
<link href="https://api.mapbox.com/mapbox-gl-js/v2.6.1/mapbox-gl.css" rel="stylesheet">
<style>
body {
margin: 0;
font-family: Helvetica, Arial, sans-serif;
}
#map {
width: 100vw;
height: 100vh;
}
.control-panel {
position: absolute;
top: 0;
right: 0;
max-width: 320px;
background: #fff;
box-shadow: 0 2px 4px rgba(0,0,0,0.3);
padding: 12px 24px;
margin: 20px;
font-size: 13px;
line-height: 2;
color: #6b6b76;
text-transform: uppercase;
outline: none;
}
</style>
</head>
<body>
<div id="map"></div>

View File

@ -1,21 +1,23 @@
{
"scripts": {
"start": "webpack-dev-server --progress --hot --open",
"start-local": "webpack-dev-server --env.local --progress --hot --open"
"start-local": "webpack-dev-server --env local --progress --hot --open"
},
"dependencies": {
"react": "^16.3.0",
"react-dom": "^16.3.0",
"react-map-gl": "^6.0.0"
"react": "^17.0.0",
"react-dom": "^17.0.0",
"react-map-gl": "^7.0.0",
"mapbox-gl": "^2.0.0"
},
"devDependencies": {
"@babel/core": "^7.0.0",
"@babel/plugin-proposal-class-properties": "^7.0.0",
"@babel/preset-env": "^7.0.0",
"@babel/preset-react": "^7.0.0",
"babel-loader": "^8.0.0",
"webpack": "^4.20.0",
"webpack-cli": "^3.1.2",
"webpack-dev-server": "^3.1.0"
"ts-loader": "^9.0.0",
"typescript": "^4.0.0",
"webpack": "^5.65.0",
"webpack-cli": "^4.9.0",
"webpack-dev-server": "^4.7.0"
}
}

View File

@ -2,13 +2,14 @@
import * as React from 'react';
import {useState, useEffect} from 'react';
import {render} from 'react-dom';
import MapGL, {Source, Layer} from 'react-map-gl';
import {Map, Source, Layer} from 'react-map-gl';
import type {LayerProps} from 'react-map-gl';
import ControlPanel from './control-panel';
const MAPBOX_TOKEN = ''; // Set your mapbox token here
const pointLayer = {
const pointLayer: LayerProps = {
type: 'circle',
paint: {
'circle-radius': 10,
@ -24,13 +25,6 @@ function pointOnCircle({center, angle, radius}) {
}
export default function App() {
const [viewport, setViewport] = useState({
latitude: 0,
longitude: -100,
zoom: 3,
bearing: 0,
pitch: 0
});
const [pointData, setPointData] = useState(null);
useEffect(() => {
@ -42,20 +36,21 @@ export default function App() {
return (
<>
<MapGL
{...viewport}
width="100%"
height="100%"
<Map
initialViewState={{
latitude: 0,
longitude: -100,
zoom: 3
}}
mapStyle="mapbox://styles/mapbox/light-v9"
onViewportChange={setViewport}
mapboxApiAccessToken={MAPBOX_TOKEN}
mapboxAccessToken={MAPBOX_TOKEN}
>
{pointData && (
<Source type="geojson" data={pointData}>
<Layer {...pointLayer} />
</Source>
)}
</MapGL>
</Map>
<ControlPanel />
</>
);

View File

@ -0,0 +1,10 @@
{
"compilerOptions": {
"target": "es2020",
"jsx": "react",
"allowSyntheticDefaultImports": true,
"resolveJsonModule": true,
"moduleResolution": "node",
"sourceMap": true
}
}

View File

@ -5,33 +5,40 @@
const resolve = require('path').resolve;
const webpack = require('webpack');
const BABEL_CONFIG = {
presets: ['@babel/env', '@babel/react'],
plugins: ['@babel/proposal-class-properties']
};
const config = {
mode: 'development',
devServer: {
static: '.'
},
entry: {
app: resolve('./src/app.js')
app: resolve('./src/app')
},
output: {
library: 'App'
},
resolve: {
extensions: ['.ts', '.tsx', '.js', '.json']
},
module: {
rules: [
{
// Compile ES2015 using babel
test: /\.js$/,
test: /\.(ts|js)x?$/,
include: [resolve('.')],
exclude: [/node_modules/],
use: [
{
loader: 'babel-loader',
options: BABEL_CONFIG
options: {
presets: ['@babel/env', '@babel/react']
}
},
{
loader: 'ts-loader'
}
]
}
@ -39,7 +46,7 @@ const config = {
},
// Optional: Enables reading mapbox token from environment variable
plugins: [new webpack.EnvironmentPlugin(['MapboxAccessToken'])]
plugins: [new webpack.EnvironmentPlugin({MapboxAccessToken: ''})]
};
// Enables bundling against src in this repo rather than the installed version

View File

@ -1,46 +0,0 @@
body {
margin: 0;
font-family: Helvetica, Arial, sans-serif;
}
#map {
width: 100vw;
height: 100vh;
}
.control-panel {
position: absolute;
top: 0;
right: 0;
max-width: 320px;
background: #fff;
box-shadow: 0 2px 4px rgba(0,0,0,0.3);
padding: 12px 24px;
margin: 20px;
font-size: 13px;
line-height: 2;
color: #6b6b76;
outline: none;
text-transform: uppercase;
}
label {
display: inline-block;
width: 100px;
}
input {
margin-left: 20px;
width: 160px;
}
.tooltip {
position: absolute;
margin: 8px;
padding: 4px;
background: rgba(0, 0, 0, 0.8);
color: #fff;
max-width: 300px;
font-size: 10px;
z-index: 9;
pointer-events: none;
}

View File

@ -3,7 +3,55 @@
<head>
<meta charset='UTF-8' />
<title>react-map-gl Example</title>
<link rel="stylesheet" type="text/css" href="app.css" />
<link href="https://api.mapbox.com/mapbox-gl-js/v2.6.1/mapbox-gl.css" rel="stylesheet">
<style>
body {
margin: 0;
font-family: Helvetica, Arial, sans-serif;
}
#map {
width: 100vw;
height: 100vh;
}
.control-panel {
position: absolute;
top: 0;
right: 0;
max-width: 320px;
background: #fff;
box-shadow: 0 2px 4px rgba(0,0,0,0.3);
padding: 12px 24px;
margin: 20px;
font-size: 13px;
line-height: 2;
color: #6b6b76;
text-transform: uppercase;
outline: none;
}
label {
display: inline-block;
width: 100px;
}
input {
margin-left: 20px;
width: 160px;
}
.tooltip {
position: absolute;
margin: 8px;
padding: 4px;
background: rgba(0, 0, 0, 0.8);
color: #fff;
max-width: 300px;
font-size: 10px;
z-index: 9;
pointer-events: none;
}
</style>
</head>
<body>
<div id="map"></div>

View File

@ -1,22 +1,25 @@
{
"scripts": {
"start": "webpack-dev-server --progress --hot --open",
"start-local": "webpack-dev-server --env.local --progress --hot --open"
"start-local": "webpack-dev-server --env local --progress --hot --open"
},
"dependencies": {
"d3-scale": "^1.0.6",
"react": "^16.3.0",
"react-dom": "^16.3.0",
"react-map-gl": "^6.0.0"
"d3-array": "^3.1.1",
"d3-scale": "^4.0.2",
"mapbox-gl": "^2.0.0",
"react": "^17.0.0",
"react-dom": "^17.0.0",
"react-map-gl": "^7.0.0"
},
"devDependencies": {
"@babel/core": "^7.0.0",
"@babel/plugin-proposal-class-properties": "^7.0.0",
"@babel/preset-env": "^7.0.0",
"@babel/preset-react": "^7.0.0",
"babel-loader": "^8.0.0",
"webpack": "^4.20.0",
"webpack-cli": "^3.1.2",
"webpack-dev-server": "^3.1.0"
"ts-loader": "^9.0.0",
"typescript": "^4.0.0",
"webpack": "^5.65.0",
"webpack-cli": "^4.9.0",
"webpack-dev-server": "^4.7.0"
}
}

View File

@ -1,22 +1,15 @@
import * as React from 'react';
import {useState, useEffect, useMemo, useCallback} from 'react';
import {render} from 'react-dom';
import MapGL, {Source, Layer} from 'react-map-gl';
import Map, {Source, Layer} from 'react-map-gl';
import ControlPanel from './control-panel';
import {dataLayer} from './map-style.js';
import {dataLayer} from './map-style';
import {updatePercentiles} from './utils';
const MAPBOX_TOKEN = ''; // Set your mapbox token here
export default function App() {
const [viewport, setViewport] = useState({
latitude: 40,
longitude: -100,
zoom: 3,
bearing: 0,
pitch: 0
});
const [year, setYear] = useState(2015);
const [allData, setAllData] = useState(null);
const [hoverInfo, setHoverInfo] = useState(null);
@ -33,7 +26,7 @@ export default function App() {
const onHover = useCallback(event => {
const {
features,
srcEvent: {offsetX, offsetY}
point: {x, y}
} = event;
const hoveredFeature = features && features[0];
@ -41,8 +34,8 @@ export default function App() {
hoveredFeature
? {
feature: hoveredFeature,
x: offsetX,
y: offsetY
x,
y
}
: null
);
@ -54,15 +47,16 @@ export default function App() {
return (
<>
<MapGL
{...viewport}
width="100%"
height="100%"
<Map
initialViewState={{
latitude: 40,
longitude: -100,
zoom: 3
}}
mapStyle="mapbox://styles/mapbox/light-v9"
onViewportChange={setViewport}
mapboxApiAccessToken={MAPBOX_TOKEN}
mapboxAccessToken={MAPBOX_TOKEN}
interactiveLayerIds={['data']}
onHover={onHover}
onMouseMove={onHover}
>
<Source type="geojson" data={data}>
<Layer {...dataLayer} />
@ -74,7 +68,7 @@ export default function App() {
<div>Percentile: {(hoverInfo.feature.properties.percentile / 8) * 100}</div>
</div>
)}
</MapGL>
</Map>
<ControlPanel year={year} onChange={value => setYear(value)} />
</>

View File

@ -1,5 +1,7 @@
import type {FillLayer} from 'react-map-gl';
// For more information on data-driven styles, see https://www.mapbox.com/help/gl-dds-ref/
export const dataLayer = {
export const dataLayer: FillLayer = {
id: 'data',
type: 'fill',
paint: {

View File

@ -1,7 +1,12 @@
import {range} from 'd3-array';
import {scaleQuantile} from 'd3-scale';
export function updatePercentiles(featureCollection, accessor) {
import type GeoJSON from 'geojson';
export function updatePercentiles(
featureCollection: GeoJSON.FeatureCollection<GeoJSON.Geometry>,
accessor: (f: GeoJSON.Feature<GeoJSON.Geometry>) => number
): GeoJSON.FeatureCollection<GeoJSON.Geometry> {
const {features} = featureCollection;
const scale = scaleQuantile().domain(features.map(accessor)).range(range(9));
return {

View File

@ -0,0 +1,10 @@
{
"compilerOptions": {
"target": "es2020",
"jsx": "react",
"allowSyntheticDefaultImports": true,
"resolveJsonModule": true,
"moduleResolution": "node",
"sourceMap": true
}
}

View File

@ -5,33 +5,40 @@
const resolve = require('path').resolve;
const webpack = require('webpack');
const BABEL_CONFIG = {
presets: ['@babel/env', '@babel/react'],
plugins: ['@babel/proposal-class-properties']
};
const config = {
mode: 'development',
devServer: {
static: '.'
},
entry: {
app: resolve('./src/app.js')
app: resolve('./src/app')
},
output: {
library: 'App'
},
resolve: {
extensions: ['.ts', '.tsx', '.js', '.json']
},
module: {
rules: [
{
// Compile ES2015 using babel
test: /\.js$/,
test: /\.(ts|js)x?$/,
include: [resolve('.')],
exclude: [/node_modules/],
use: [
{
loader: 'babel-loader',
options: BABEL_CONFIG
options: {
presets: ['@babel/env', '@babel/react']
}
},
{
loader: 'ts-loader'
}
]
}
@ -39,7 +46,7 @@ const config = {
},
// Optional: Enables reading mapbox token from environment variable
plugins: [new webpack.EnvironmentPlugin(['MapboxAccessToken'])]
plugins: [new webpack.EnvironmentPlugin({MapboxAccessToken: ''})]
};
// Enables bundling against src in this repo rather than the installed version

View File

@ -1,38 +0,0 @@
body {
margin: 0;
font-family: Helvetica, Arial, sans-serif;
}
#map {
width: 100vw;
height: 100vh;
}
.control-panel {
position: absolute;
top: 0;
right: 0;
max-width: 320px;
background: #fff;
box-shadow: 0 2px 4px rgba(0,0,0,0.3);
padding: 12px 24px;
margin: 20px;
font-size: 13px;
line-height: 2;
color: #6b6b76;
outline: none;
text-transform: uppercase;
}
label {
display: inline-block;
width: 150px;
}
input {
margin-left: 20px;
}
.input.disabled {
opacity: .5;
cursor: not-allowed;
}

View File

@ -3,7 +3,46 @@
<head>
<meta charset='UTF-8' />
<title>react-map-gl Example</title>
<link rel="stylesheet" type="text/css" href="app.css" />
<link href="https://api.mapbox.com/mapbox-gl-js/v2.6.1/mapbox-gl.css" rel="stylesheet">
<style>
body {
margin: 0;
font-family: Helvetica, Arial, sans-serif;
}
#map {
width: 100vw;
height: 100vh;
}
.control-panel {
position: absolute;
top: 0;
right: 0;
max-width: 320px;
background: #fff;
box-shadow: 0 2px 4px rgba(0,0,0,0.3);
padding: 12px 24px;
margin: 20px;
font-size: 13px;
line-height: 2;
color: #6b6b76;
text-transform: uppercase;
outline: none;
}
label {
display: inline-block;
width: 150px;
}
input {
margin-left: 20px;
}
.input.disabled {
opacity: .5;
cursor: not-allowed;
}
</style>
</head>
<body>
<div id="map"></div>

View File

@ -1,21 +1,23 @@
{
"scripts": {
"start": "webpack-dev-server --progress --hot --open",
"start-local": "webpack-dev-server --env.local --progress --hot --open"
"start-local": "webpack-dev-server --env local --progress --hot --open"
},
"dependencies": {
"react": "^16.3.0",
"react-dom": "^16.3.0",
"react-map-gl": "^6.0.0"
"react": "^17.0.0",
"react-dom": "^17.0.0",
"react-map-gl": "^7.0.0",
"mapbox-gl": "^2.0.0"
},
"devDependencies": {
"@babel/core": "^7.0.0",
"@babel/plugin-proposal-class-properties": "^7.0.0",
"@babel/preset-env": "^7.0.0",
"@babel/preset-react": "^7.0.0",
"babel-loader": "^8.0.0",
"webpack": "^4.20.0",
"webpack-cli": "^3.1.2",
"webpack-dev-server": "^3.1.0"
"ts-loader": "^9.0.0",
"typescript": "^4.0.0",
"webpack": "^5.65.0",
"webpack-cli": "^4.9.0",
"webpack-dev-server": "^4.7.0"
}
}

View File

@ -24,13 +24,6 @@ function filterFeaturesByDay(featureCollection, time) {
}
export default function App() {
const [viewport, setViewport] = useState({
latitude: 40,
longitude: -100,
zoom: 3,
bearing: 0,
pitch: 0
});
const [allDays, useAllDays] = useState(true);
const [timeRange, setTimeRange] = useState([0, 0]);
const [selectedTime, selectTime] = useState(0);
@ -60,12 +53,13 @@ export default function App() {
return (
<>
<MapGL
{...viewport}
width="100%"
height="100%"
initialViewState={{
latitude: 40,
longitude: -100,
zoom: 3
}}
mapStyle="mapbox://styles/mapbox/dark-v9"
onViewportChange={setViewport}
mapboxApiAccessToken={MAPBOX_TOKEN}
mapboxAccessToken={MAPBOX_TOKEN}
>
{data && (
<Source type="geojson" data={data}>

View File

@ -1,6 +1,9 @@
import type {HeatmapLayer} from 'react-map-gl';
const MAX_ZOOM_LEVEL = 9;
export const heatmapLayer = {
export const heatmapLayer: HeatmapLayer = {
id: 'heatmap',
maxzoom: MAX_ZOOM_LEVEL,
type: 'heatmap',
paint: {

View File

@ -0,0 +1,10 @@
{
"compilerOptions": {
"target": "es2020",
"jsx": "react",
"allowSyntheticDefaultImports": true,
"resolveJsonModule": true,
"moduleResolution": "node",
"sourceMap": true
}
}

View File

@ -5,33 +5,40 @@
const resolve = require('path').resolve;
const webpack = require('webpack');
const BABEL_CONFIG = {
presets: ['@babel/env', '@babel/react'],
plugins: ['@babel/proposal-class-properties']
};
const config = {
mode: 'development',
devServer: {
static: '.'
},
entry: {
app: resolve('./src/app.js')
app: resolve('./src/app')
},
output: {
library: 'App'
},
resolve: {
extensions: ['.ts', '.tsx', '.js', '.json']
},
module: {
rules: [
{
// Compile ES2015 using babel
test: /\.js$/,
test: /\.(ts|js)x?$/,
include: [resolve('.')],
exclude: [/node_modules/],
use: [
{
loader: 'babel-loader',
options: BABEL_CONFIG
options: {
presets: ['@babel/env', '@babel/react']
}
},
{
loader: 'ts-loader'
}
]
}
@ -39,7 +46,7 @@ const config = {
},
// Optional: Enables reading mapbox token from environment variable
plugins: [new webpack.EnvironmentPlugin(['MapboxAccessToken'])]
plugins: [new webpack.EnvironmentPlugin({MapboxAccessToken: ''})]
};
// Enables bundling against src in this repo rather than the installed version

View File

@ -1,33 +0,0 @@
body {
margin: 0;
font-family: Helvetica, Arial, sans-serif;
}
#map {
width: 100vw;
height: 100vh;
}
.control-panel {
position: absolute;
top: 0;
right: 0;
max-width: 320px;
background: #fff;
box-shadow: 0 2px 4px rgba(0,0,0,0.3);
padding: 12px 24px;
margin: 20px;
font-size: 13px;
line-height: 2;
color: #6b6b76;
text-transform: uppercase;
outline: none;
}
label {
display: inline-block;
width: 100px;
}
input {
margin-left: 20px;
}

View File

@ -3,7 +3,41 @@
<head>
<meta charset='UTF-8' />
<title>react-map-gl Example</title>
<link rel="stylesheet" type="text/css" href="app.css" />
<link href="https://api.mapbox.com/mapbox-gl-js/v2.6.1/mapbox-gl.css" rel="stylesheet">
<style>
body {
margin: 0;
font-family: Helvetica, Arial, sans-serif;
}
#map {
width: 100vw;
height: 100vh;
}
.control-panel {
position: absolute;
top: 0;
right: 0;
max-width: 320px;
background: #fff;
box-shadow: 0 2px 4px rgba(0,0,0,0.3);
padding: 12px 24px;
margin: 20px;
font-size: 13px;
line-height: 2;
color: #6b6b76;
text-transform: uppercase;
outline: none;
}
label {
display: inline-block;
width: 150px;
}
input {
margin-left: 20px;
}
</style>
</head>
<body>
<div id="map"></div>

View File

@ -1,22 +1,24 @@
{
"scripts": {
"start": "webpack-dev-server --progress --hot --open",
"start-local": "webpack-dev-server --env.local --progress --hot --open"
"start-local": "webpack-dev-server --env local --progress --hot --open"
},
"dependencies": {
"immutable": "^3.8.1",
"react": "^16.3.0",
"react-dom": "^16.3.0",
"react-map-gl": "^6.0.0"
"immutable": "^4.0.0",
"mapbox-gl": "^2.0.0",
"react": "^17.0.0",
"react-dom": "^17.0.0",
"react-map-gl": "^7.0.0"
},
"devDependencies": {
"@babel/core": "^7.0.0",
"@babel/plugin-proposal-class-properties": "^7.0.0",
"@babel/preset-env": "^7.0.0",
"@babel/preset-react": "^7.0.0",
"babel-loader": "^8.0.0",
"webpack": "^4.20.0",
"webpack-cli": "^3.1.2",
"webpack-dev-server": "^3.1.0"
"ts-loader": "^9.0.0",
"typescript": "^4.0.0",
"webpack": "^5.65.0",
"webpack-cli": "^4.9.0",
"webpack-dev-server": "^4.7.0"
}
}

View File

@ -1,37 +0,0 @@
import * as React from 'react';
import {useState} from 'react';
import {render} from 'react-dom';
import MapGL from 'react-map-gl';
import ControlPanel from './control-panel';
const MAPBOX_TOKEN = ''; // Set your mapbox token here
export default function App() {
const [viewport, setViewport] = useState({
latitude: 37.805,
longitude: -122.447,
zoom: 15.5,
bearing: 0,
pitch: 0
});
const [mapStyle, setMapStyle] = useState('');
return (
<>
<MapGL
{...viewport}
width="100%"
height="100%"
mapStyle={mapStyle}
onViewportChange={setViewport}
mapboxApiAccessToken={MAPBOX_TOKEN}
/>
<ControlPanel onChange={setMapStyle} />
</>
);
}
export function renderToDom(container) {
render(<App />, container);
}

View File

@ -0,0 +1,32 @@
import * as React from 'react';
import {useState} from 'react';
import {render} from 'react-dom';
import Map from 'react-map-gl';
import ControlPanel from './control-panel';
const MAPBOX_TOKEN = ''; // Set your mapbox token here
export default function App() {
const [mapStyle, setMapStyle] = useState(null);
return (
<>
<Map
initialViewState={{
latitude: 37.805,
longitude: -122.447,
zoom: 15.5
}}
mapStyle={mapStyle && mapStyle.toJS()}
styleDiffing
mapboxAccessToken={MAPBOX_TOKEN}
/>
<ControlPanel onChange={setMapStyle} />
</>
);
}
export function renderToDom(container) {
render(<App />, container);
}

View File

@ -3,7 +3,7 @@ import {useState, useEffect} from 'react';
import {fromJS} from 'immutable';
import MAP_STYLE from '../../map-style-basic-v8.json';
const defaultMapStyle = fromJS(MAP_STYLE);
const defaultMapStyle: any = fromJS(MAP_STYLE);
const defaultLayers = defaultMapStyle.get('layers');
const categories = ['labels', 'roads', 'buildings', 'parks', 'water', 'background'];

View File

@ -0,0 +1,10 @@
{
"compilerOptions": {
"target": "es2020",
"jsx": "react",
"allowSyntheticDefaultImports": true,
"resolveJsonModule": true,
"moduleResolution": "node",
"sourceMap": true
}
}

View File

@ -5,33 +5,40 @@
const resolve = require('path').resolve;
const webpack = require('webpack');
const BABEL_CONFIG = {
presets: ['@babel/env', '@babel/react'],
plugins: ['@babel/proposal-class-properties']
};
const config = {
mode: 'development',
devServer: {
static: '.'
},
entry: {
app: resolve('./src/app.js')
app: resolve('./src/app')
},
output: {
library: 'App'
},
resolve: {
extensions: ['.ts', '.tsx', '.js', '.json']
},
module: {
rules: [
{
// Compile ES2015 using babel
test: /\.js$/,
test: /\.(ts|js)x?$/,
include: [resolve('.')],
exclude: [/node_modules/],
use: [
{
loader: 'babel-loader',
options: BABEL_CONFIG
options: {
presets: ['@babel/env', '@babel/react']
}
},
{
loader: 'ts-loader'
}
]
}
@ -39,7 +46,7 @@ const config = {
},
// Optional: Enables reading mapbox token from environment variable
plugins: [new webpack.EnvironmentPlugin(['MapboxAccessToken'])]
plugins: [new webpack.EnvironmentPlugin({MapboxAccessToken: ''})]
};
// Enables bundling against src in this repo rather than the installed version

View File

@ -1,12 +0,0 @@
# Example: Locate User
Demonstrates how to automatically locate the user and track their current location with react-map-gl.
## Usage
To run this example, you need a [Mapbox token](http://visgl.github.io/react-map-gl/docs/get-started/mapbox-tokens). You can either set it as `MAPBOX_TOKEN` in `src/app.js`, or set a `MapboxAccessToken` environment variable in the command line.
```bash
npm i
npm run start
```

View File

@ -1,8 +0,0 @@
body {
margin: 0;
font-family: Helvetica, Arial, sans-serif;
}
#map {
width: 100vw;
height: 100vh;
}

View File

@ -1,15 +0,0 @@
<!doctype html>
<html>
<head>
<meta charset='UTF-8' />
<title>react-map-gl Example</title>
<link rel="stylesheet" type="text/css" href="app.css" />
</head>
<body>
<div id="map"></div>
<script src='app.js'></script>
</body>
<script type="text/javascript">
App.renderToDom(document.getElementById('map'));
</script>
</html>

View File

@ -1,22 +0,0 @@
{
"scripts": {
"start": "webpack-dev-server --progress --hot --open",
"start-local": "webpack-dev-server --env.local --progress --hot --open"
},
"dependencies": {
"immutable": "^3.8.1",
"react": "^16.3.0",
"react-dom": "^16.3.0",
"react-map-gl": "^6.0.0"
},
"devDependencies": {
"@babel/core": "^7.0.0",
"@babel/plugin-proposal-class-properties": "^7.0.0",
"@babel/preset-env": "^7.0.0",
"@babel/preset-react": "^7.0.0",
"babel-loader": "^8.0.0",
"webpack": "^4.20.0",
"webpack-cli": "^3.1.2",
"webpack-dev-server": "^3.1.0"
}
}

View File

@ -1,45 +0,0 @@
import * as React from 'react';
import {useState} from 'react';
import {render} from 'react-dom';
import MapGL, {GeolocateControl} from 'react-map-gl';
const MAPBOX_TOKEN = ''; // Set your mapbox token here
const geolocateStyle = {
top: 0,
left: 0,
margin: 10
};
const positionOptions = {enableHighAccuracy: true};
export default function App() {
const [viewport, setViewport] = useState({
latitude: 37.8,
longitude: 96,
zoom: 3,
bearing: 0,
pitch: 0
});
return (
<MapGL
{...viewport}
width="100%"
height="100%"
mapStyle="mapbox://styles/mapbox/dark-v9"
onViewportChange={setViewport}
mapboxApiAccessToken={MAPBOX_TOKEN}
>
<GeolocateControl
style={geolocateStyle}
positionOptions={positionOptions}
trackUserLocation
auto
/>
</MapGL>
);
}
export function renderToDom(container) {
render(<App />, container);
}

View File

@ -1,47 +0,0 @@
// NOTE: To use this example standalone (e.g. outside of repo)
// delete the local development overrides at the bottom of this file
// avoid destructuring for older Node version support
const resolve = require('path').resolve;
const webpack = require('webpack');
const BABEL_CONFIG = {
presets: ['@babel/env', '@babel/react'],
plugins: ['@babel/proposal-class-properties']
};
const config = {
mode: 'development',
entry: {
app: resolve('./src/app.js')
},
output: {
library: 'App'
},
module: {
rules: [
{
// Compile ES2015 using babel
test: /\.js$/,
include: [resolve('.')],
exclude: [/node_modules/],
use: [
{
loader: 'babel-loader',
options: BABEL_CONFIG
}
]
}
]
},
// Optional: Enables reading mapbox token from environment variable
plugins: [new webpack.EnvironmentPlugin(['MapboxAccessToken'])]
};
// Enables bundling against src in this repo rather than the installed version
module.exports = env =>
env && env.local ? require('../webpack.config.local')(config)(env) : config;

View File

@ -1,24 +0,0 @@
body {
margin: 0;
background: #000;
}
#map {
width: 100vw;
height: 100vh;
}
.control-panel {
position: absolute;
top: 0;
right: 0;
max-width: 320px;
background: #fff;
box-shadow: 0 2px 4px rgba(0,0,0,0.3);
padding: 12px 24px;
margin: 20px;
font-size: 13px;
line-height: 2;
color: #6b6b76;
text-transform: uppercase;
outline: none;
}

View File

@ -3,7 +3,33 @@
<head>
<meta charset='UTF-8' />
<title>react-map-gl Example</title>
<link rel="stylesheet" type="text/css" href="app.css" />
<link href="https://api.mapbox.com/mapbox-gl-js/v2.6.1/mapbox-gl.css" rel="stylesheet">
<style>
body {
margin: 0;
font-family: Helvetica, Arial, sans-serif;
}
#map {
width: 100vw;
height: 100vh;
}
.control-panel {
position: absolute;
top: 0;
right: 0;
max-width: 320px;
background: #fff;
box-shadow: 0 2px 4px rgba(0,0,0,0.3);
padding: 12px 24px;
margin: 20px;
font-size: 13px;
line-height: 2;
color: #6b6b76;
text-transform: uppercase;
outline: none;
}
</style>
</head>
<body>
<div id="map"></div>

View File

@ -1,21 +1,24 @@
{
"scripts": {
"start": "webpack-dev-server --progress --hot --open",
"start-local": "webpack-dev-server --env.local --progress --hot --open"
"start-local": "webpack-dev-server --env local --progress --hot --open"
},
"dependencies": {
"react": "^16.3.0",
"react-dom": "^16.3.0",
"react-map-gl": "^6.1.0"
"@turf/bbox": "^6.5.0",
"mapbox-gl": "^2.0.0",
"react": "^17.0.0",
"react-dom": "^17.0.0",
"react-map-gl": "^7.0.0"
},
"devDependencies": {
"@babel/core": "^7.0.0",
"@babel/plugin-proposal-class-properties": "^7.0.0",
"@babel/preset-env": "^7.0.0",
"@babel/preset-react": "^7.0.0",
"babel-loader": "^8.0.0",
"webpack": "^4.20.0",
"webpack-cli": "^3.1.2",
"webpack-dev-server": "^3.1.0"
"ts-loader": "^9.0.0",
"typescript": "^4.0.0",
"webpack": "^5.65.0",
"webpack-cli": "^4.9.0",
"webpack-dev-server": "^4.7.0"
}
}

View File

@ -1,13 +1,15 @@
import * as React from 'react';
import {useState, useCallback} from 'react';
import {useCallback} from 'react';
import {render} from 'react-dom';
import MapGL, {Source, Layer} from 'react-map-gl';
import Map, {Source, Layer} from 'react-map-gl';
import ControlPanel from './control-panel';
import type {SkyLayer} from 'react-map-gl';
const TOKEN = ''; // Set your mapbox token here
const skyLayer = {
const skyLayer: SkyLayer = {
id: 'sky',
type: 'sky',
paint: {
@ -18,14 +20,6 @@ const skyLayer = {
};
export default function App() {
const [viewport, setViewport] = useState({
latitude: 32.6141,
longitude: -114.34411,
zoom: 14,
bearing: 80,
pitch: 80
});
const onMapLoad = useCallback(evt => {
const map = evt.target;
map.setTerrain({source: 'mapbox-dem', exaggeration: 1.5});
@ -33,13 +27,16 @@ export default function App() {
return (
<>
<MapGL
{...viewport}
width="100%"
height="100%"
<Map
initialViewState={{
latitude: 32.6141,
longitude: -114.34411,
zoom: 14,
bearing: 80,
pitch: 80
}}
mapStyle="mapbox://styles/mapbox/satellite-v9"
onViewportChange={setViewport}
mapboxApiAccessToken={TOKEN}
mapboxAccessToken={TOKEN}
onLoad={onMapLoad}
>
<Source
@ -50,7 +47,7 @@ export default function App() {
maxzoom={14}
/>
<Layer {...skyLayer} />
</MapGL>
</Map>
<ControlPanel />
</>
);

View File

@ -0,0 +1,10 @@
{
"compilerOptions": {
"target": "es2020",
"jsx": "react",
"allowSyntheticDefaultImports": true,
"resolveJsonModule": true,
"moduleResolution": "node",
"sourceMap": true
}
}

View File

@ -5,33 +5,40 @@
const resolve = require('path').resolve;
const webpack = require('webpack');
const BABEL_CONFIG = {
presets: ['@babel/env', '@babel/react'],
plugins: ['@babel/proposal-class-properties']
};
const config = {
mode: 'development',
devServer: {
static: '.'
},
entry: {
app: resolve('./src/app.js')
app: resolve('./src/app')
},
output: {
library: 'App'
},
resolve: {
extensions: ['.ts', '.tsx', '.js', '.json']
},
module: {
rules: [
{
// Compile ES2015 using babel
test: /\.js$/,
test: /\.(ts|js)x?$/,
include: [resolve('.')],
exclude: [/node_modules/],
use: [
{
loader: 'babel-loader',
options: BABEL_CONFIG
options: {
presets: ['@babel/env', '@babel/react']
}
},
{
loader: 'ts-loader'
}
]
}
@ -39,7 +46,7 @@ const config = {
},
// Optional: Enables reading mapbox token from environment variable
plugins: [new webpack.EnvironmentPlugin(['MapboxAccessToken'])]
plugins: [new webpack.EnvironmentPlugin({MapboxAccessToken: ''})]
};
// Enables bundling against src in this repo rather than the installed version

View File

@ -1,24 +0,0 @@
body {
margin: 0;
background: #000;
}
#map {
width: 100vw;
height: 100vh;
}
.control-panel {
position: absolute;
top: 0;
right: 0;
max-width: 320px;
background: #fff;
box-shadow: 0 2px 4px rgba(0,0,0,0.3);
padding: 12px 24px;
margin: 20px;
font-size: 13px;
line-height: 2;
color: #6b6b76;
text-transform: uppercase;
outline: none;
}

View File

@ -3,7 +3,33 @@
<head>
<meta charset='UTF-8' />
<title>react-map-gl Example</title>
<link rel="stylesheet" type="text/css" href="app.css" />
<link href="https://api.mapbox.com/mapbox-gl-js/v2.6.1/mapbox-gl.css" rel="stylesheet">
<style>
body {
margin: 0;
font-family: Helvetica, Arial, sans-serif;
}
#map {
width: 100vw;
height: 100vh;
}
.control-panel {
position: absolute;
top: 0;
right: 0;
max-width: 320px;
background: #fff;
box-shadow: 0 2px 4px rgba(0,0,0,0.3);
padding: 12px 24px;
margin: 20px;
font-size: 13px;
line-height: 2;
color: #6b6b76;
text-transform: uppercase;
outline: none;
}
</style>
</head>
<body>
<div id="map"></div>

View File

@ -1,22 +1,24 @@
{
"scripts": {
"start": "webpack-dev-server --progress --hot --open",
"start-local": "webpack-dev-server --env.local --progress --hot --open"
"start-local": "webpack-dev-server --env local --progress --hot --open"
},
"dependencies": {
"@turf/bbox": "^6.0.1",
"react": "^16.3.0",
"react-dom": "^16.3.0",
"react-map-gl": "^6.0.0"
"@turf/bbox": "^6.5.0",
"mapbox-gl": "^2.0.0",
"react": "^17.0.0",
"react-dom": "^17.0.0",
"react-map-gl": "^7.0.0"
},
"devDependencies": {
"@babel/core": "^7.0.0",
"@babel/plugin-proposal-class-properties": "^7.0.0",
"@babel/preset-env": "^7.0.0",
"@babel/preset-react": "^7.0.0",
"babel-loader": "^8.0.0",
"webpack": "^4.20.0",
"webpack-cli": "^3.1.2",
"webpack-dev-server": "^3.1.0"
"ts-loader": "^9.0.0",
"typescript": "^4.0.0",
"webpack": "^5.65.0",
"webpack-cli": "^4.9.0",
"webpack-dev-server": "^4.7.0"
}
}

View File

@ -1,70 +0,0 @@
import * as React from 'react';
import {useState} from 'react';
import {render} from 'react-dom';
import MapGL, {LinearInterpolator, WebMercatorViewport} from 'react-map-gl';
import bbox from '@turf/bbox';
import ControlPanel from './control-panel';
import MAP_STYLE from './map-style';
const TOKEN = ''; // Set your mapbox token here
export default function App() {
const [viewport, setViewport] = useState({
latitude: 37.78,
longitude: -122.4,
zoom: 11,
bearing: 0,
pitch: 0
});
const onClick = event => {
const feature = event.features[0];
if (feature) {
// calculate the bounding box of the feature
const [minLng, minLat, maxLng, maxLat] = bbox(feature);
// construct a viewport instance from the current state
const vp = new WebMercatorViewport(viewport);
const {longitude, latitude, zoom} = vp.fitBounds(
[
[minLng, minLat],
[maxLng, maxLat]
],
{
padding: 40
}
);
setViewport({
...viewport,
longitude,
latitude,
zoom,
transitionInterpolator: new LinearInterpolator({
around: [event.offsetCenter.x, event.offsetCenter.y]
}),
transitionDuration: 1000
});
}
};
return (
<>
<MapGL
{...viewport}
width="100%"
height="100%"
mapStyle={MAP_STYLE}
interactiveLayerIds={['sf-neighborhoods-fill']}
onClick={onClick}
onViewportChange={v => setViewport(v)}
mapboxApiAccessToken={TOKEN}
/>
<ControlPanel />
</>
);
}
export function renderToDom(container) {
render(<App />, container);
}

View File

@ -0,0 +1,56 @@
import * as React from 'react';
import {useRef} from 'react';
import {render} from 'react-dom';
import Map from 'react-map-gl';
import bbox from '@turf/bbox';
import ControlPanel from './control-panel';
import MAP_STYLE from './map-style';
import type {MapboxStyle, MapRef, MapLayerMouseEvent} from 'react-map-gl';
const TOKEN = ''; // Set your mapbox token here
export default function App() {
const mapRef = useRef<MapRef>();
const onClick = (event: MapLayerMouseEvent) => {
const feature = event.features[0];
if (feature) {
const map = mapRef.current.getMap();
// calculate the bounding box of the feature
const [minLng, minLat, maxLng, maxLat] = bbox(feature);
map.fitBounds(
[
[minLng, minLat],
[maxLng, maxLat]
],
{padding: 40, duration: 1000}
);
}
};
return (
<>
<Map
ref={mapRef}
initialViewState={{
latitude: 37.78,
longitude: -122.4,
zoom: 11
}}
mapStyle={MAP_STYLE as MapboxStyle}
interactiveLayerIds={['sf-neighborhoods-fill']}
onClick={onClick}
mapboxAccessToken={TOKEN}
/>
<ControlPanel />
</>
);
}
export function renderToDom(container) {
render(<App />, container);
}

View File

@ -1,37 +0,0 @@
import MAP_STYLE from '../../map-style-basic-v8.json';
// Make a copy of the map style
const mapStyle = {
...MAP_STYLE,
sources: {...MAP_STYLE.sources},
layers: MAP_STYLE.layers.slice()
};
mapStyle.sources['sf-neighborhoods'] = {
type: 'geojson',
data: 'https://raw.githubusercontent.com/uber/react-map-gl/master/examples/.data/feature-example-sf.json'
};
mapStyle.layers.push(
{
id: 'sf-neighborhoods-fill',
source: 'sf-neighborhoods',
type: 'fill',
paint: {
'fill-outline-color': '#0040c8',
'fill-color': '#fff',
'fill-opacity': 0
}
},
{
id: 'sf-neighborhoods-outline',
source: 'sf-neighborhoods',
type: 'line',
paint: {
'line-width': 2,
'line-color': '#0080ef'
}
}
);
export default mapStyle;

View File

@ -0,0 +1,39 @@
import type {GeoJSONSourceRaw, FillLayer, LineLayer} from 'react-map-gl';
import MAP_STYLE from '../../map-style-basic-v8.json';
const sfNeighborhoods: GeoJSONSourceRaw = {
type: 'geojson',
data: 'https://raw.githubusercontent.com/uber/react-map-gl/master/examples/.data/feature-example-sf.json'
};
const fillLayer: FillLayer = {
id: 'sf-neighborhoods-fill',
source: 'sf-neighborhoods',
type: 'fill',
paint: {
'fill-outline-color': '#0040c8',
'fill-color': '#fff',
'fill-opacity': 0
}
};
const lineLayer: LineLayer = {
id: 'sf-neighborhoods-outline',
source: 'sf-neighborhoods',
type: 'line',
paint: {
'line-width': 2,
'line-color': '#0080ef'
}
};
// Make a copy of the map style
export default {
...MAP_STYLE,
sources: {
...MAP_STYLE.sources,
['sf-neighborhoods']: sfNeighborhoods
},
layers: [...MAP_STYLE.layers, fillLayer, lineLayer]
};

View File

@ -0,0 +1,10 @@
{
"compilerOptions": {
"target": "es2020",
"jsx": "react",
"allowSyntheticDefaultImports": true,
"resolveJsonModule": true,
"moduleResolution": "node",
"sourceMap": true
}
}

View File

@ -5,33 +5,40 @@
const resolve = require('path').resolve;
const webpack = require('webpack');
const BABEL_CONFIG = {
presets: ['@babel/env', '@babel/react'],
plugins: ['@babel/proposal-class-properties']
};
const config = {
mode: 'development',
devServer: {
static: '.'
},
entry: {
app: resolve('./src/app.js')
app: resolve('./src/app')
},
output: {
library: 'App'
},
resolve: {
extensions: ['.ts', '.tsx', '.js', '.json']
},
module: {
rules: [
{
// Compile ES2015 using babel
test: /\.js$/,
test: /\.(ts|js)x?$/,
include: [resolve('.')],
exclude: [/node_modules/],
use: [
{
loader: 'babel-loader',
options: BABEL_CONFIG
options: {
presets: ['@babel/env', '@babel/react']
}
},
{
loader: 'ts-loader'
}
]
}
@ -39,7 +46,7 @@ const config = {
},
// Optional: Enables reading mapbox token from environment variable
plugins: [new webpack.EnvironmentPlugin(['MapboxAccessToken'])]
plugins: [new webpack.EnvironmentPlugin({MapboxAccessToken: ''})]
};
// Enables bundling against src in this repo rather than the installed version

View File

@ -23,7 +23,7 @@
"README.md"
],
"scripts": {
"typecheck": "tsc src/**/*.* --jsx react --noEmit",
"typecheck": "tsc -p tsconfig.esm.json --noEmit",
"bootstrap": "PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true yarn && ocular-bootstrap",
"build": "ocular-clean && tsc -b tsconfig.esm.json && tsc -b tsconfig.es5.json && npm run flowgen",
"flowgen": "for i in $(find dist -type f -name \"*.d.ts\"); do sh -c \"flowgen $i -o ${i%.*.*}.js.flow\"; done;",

View File

@ -8,7 +8,7 @@ import type {
ViewState,
ViewStateChangeEvent,
MapboxOptions,
Style,
MapboxStyle,
ImmutableLike,
LngLatBoundsLike,
FitBoundsOptions,
@ -42,7 +42,7 @@ export type MapboxProps = Omit<
viewState?: ViewState;
/** Mapbox style */
mapStyle?: string | Style | ImmutableLike;
mapStyle?: string | MapboxStyle | ImmutableLike;
/** Enable diffing when the map style changes */
styleDiffing?: boolean;
/** Default layers to query on pointer events */
@ -516,13 +516,20 @@ export default class Mapbox {
this._updateHover(event);
break;
}
if (typeof event === 'object' && event.type in cameraEvents) {
(event as ViewStateChangeEvent).viewState = transformToViewState(tr);
if (eventType in cameraEvents) {
if (typeof event === 'object') {
(event as ViewStateChangeEvent).viewState = transformToViewState(tr);
}
if (this._map.isMoving()) {
// Replace map.transform with ours during the callbacks
map.transform = this._renderTransform;
baseFire.call(map, event, properties);
map.transform = tr;
return map;
}
}
// Replace map.transform with ours during the callbacks
map.transform = this._renderTransform;
baseFire.call(map, event, properties);
map.transform = tr;
return map;
}

View File

@ -1,11 +1,11 @@
import {ImmutableLike, Style} from './types';
import {ImmutableLike, MapboxStyle} from './types';
const refProps = ['type', 'source', 'source-layer', 'minzoom', 'maxzoom', 'filter', 'layout'];
// Prepare a map style object for diffing
// If immutable - convert to plain object
// Work around some issues in older styles that would fail Mapbox's diffing
export function normalizeStyle(style: string | Style | ImmutableLike): string | Style {
export function normalizeStyle(style: string | MapboxStyle | ImmutableLike): string | MapboxStyle {
if (!style) {
return null;
}
@ -13,7 +13,7 @@ export function normalizeStyle(style: string | Style | ImmutableLike): string |
return style;
}
if ('toJS' in style) {
style = style.toJS() as Style;
style = style.toJS() as MapboxStyle;
}
const layerIndex = {};

View File

@ -1,4 +1,4 @@
import type {PaddingOptions, MapboxEvent, LngLatLike} from 'mapbox-gl';
import type {PaddingOptions, MapboxEvent, LngLat} from 'mapbox-gl';
/** Defines the projection that the map should be rendered in */
export type ProjectionSpecification = {
@ -35,7 +35,7 @@ export type ViewStateChangeEvent = MapboxEvent & {
};
export type MarkerDragEvent = MapboxEvent & {
lngLat: LngLatLike;
lngLat: LngLat;
};
export type GeolocateEvent = MapboxEvent & GeolocationPosition;
@ -50,8 +50,11 @@ export interface ImmutableLike {
// re-export mapbox types
export type {
Point,
PointLike,
LngLat,
LngLatLike,
LngLatBounds,
LngLatBoundsLike,
MapboxOptions,
MarkerOptions,
@ -59,7 +62,7 @@ export type {
PaddingOptions,
PositionOptions,
FitBoundsOptions,
Style,
Style as MapboxStyle,
AnyLayer,
BackgroundLayer,
CircleLayer,

View File

@ -1,6 +1,5 @@
{
"compilerOptions": {
"build": true,
"target": "es5",
"jsx": "react",
"moduleResolution": "node",

View File

@ -1,6 +1,5 @@
{
"compilerOptions": {
"build": true,
"target": "es2020",
"jsx": "react",
"moduleResolution": "node",