- We'll Talk About:
- What is react-leaflet ?
- How to add Baidu maps tile ?
- How to create custom CRS for Baidu maps ?
- Demo Link is in the end
1. What is react-leaflet ?
Leaflet is open-source JavaScript library for mobile-friendly interactive maps, it'll let you do what ever you want like adding markers, popups, shapes, etc...
2. How to add Baidu maps tile
1-create new react app
2- Install the required dependencies
npm i leaflet @types/leaflet react-leaflet proj4 @types/proj4 proj4leaflet @types/proj4leaflet
or
yarn add leaflet @types/leaflet react-leaflet proj4 @types/proj4 proj4leaflet @types/proj4leaflet
3- open your app in vscode or whatever is convenient and run the project
4- in App.tsx, import leaflet css file and proj4leaflet (IMPORTATNT).
import "leaflet/dist/leaflet.css";
import "proj4leaflet";
5- import MapContainer, TileLayer from react-leaflet.
Your App.tsx should be like this.
import { MapContainer, TileLayer } from "react-leaflet";
// πππ don't forget those they are so important πππ
import "leaflet/dist/leaflet.css";
import "proj4leaflet";
function App() {
return (
<div>
<MapContainer
style={{
height: "100vh",
width: "100%",
}}
center={[31.432026740690574, 120.8439179532812]}
zoom={8}
>
<TileLayer
// those two url are the same i just add both in case one of them get out of service
url="https://maponline{s}.bdimg.com/onlinelabel/?qt=tile&x={x}&y={y}&z={z}&styles=pl"
//url="http://online{s}.map.bdimg.com/onlinelabel/?qt=tile&x={x}&y={y}&z={z}&styles=pl&scaler=1&p=1"
subdomains={["0", "1", "2", "3"]}
maxNativeZoom={18}
minNativeZoom={3}
tms
/>
</MapContainer>
</div>
);
}
export default App;
6- the map won't work because you need to pass crs as prop to the MapContainer component
3. How to create custom CRS for Baidu maps
1-create the crs
import { bounds, Proj } from "leaflet";
// create offset incase you want to adjust the map
const offset = { x: 40, y: -210 };
// create custom CRS for Baidu maps
// π₯π₯π₯ important π₯π₯π₯ this CRS only work with Baidu map Tile
// if you have multi Tiles they'll break
const baiduCRS = new Proj.CRS(
"EPSG:3395",
`+proj=merc +lon_0=0 +k=1 +x_0=${offset.x} +y_0=${offset.y} +datum=WGS84 +units=m +no_defs`,
{
resolutions: [
262144, 131072, 65536, 32768, 16384, 8192, 4096, 2048, 1024, 512, 256,
128, 64, 32, 16, 8, 4, 2, 1,
],
origin: [0, 0],
bounds: bounds([20037508.342789244, 0], [0, 20037508.342789244]),
}
);
2- Pass it to MapContainer as a prop.
The whole code will be like this.
import { MapContainer, TileLayer } from "react-leaflet";
import { bounds, Proj } from "leaflet";
// πππ don't forget those they are so important πππ
import "leaflet/dist/leaflet.css";
import "proj4leaflet";
// create offset incase you want to adjust the map
const offset = { x: 40, y: -210 };
// create costume CRS for Baidu maps
// π₯π₯π₯ important π₯π₯π₯ this CRS only work with Baidu map Tile
// if you have multi Tiles they'll break
const baiduCRS = new Proj.CRS(
"EPSG:3395",
`+proj=merc +lon_0=0 +k=1 +x_0=${offset.x} +y_0=${offset.y} +datum=WGS84 +units=m +no_defs`,
{
resolutions: [
262144, 131072, 65536, 32768, 16384, 8192, 4096, 2048, 1024, 512, 256,
128, 64, 32, 16, 8, 4, 2, 1,
],
origin: [0, 0],
bounds: bounds([20037508.342789244, 0], [0, 20037508.342789244]),
}
);
function App() {
return (
<div>
<MapContainer
style={{
height: "100vh",
width: "100%",
}}
// add the CRS here
crs={baiduCRS}
center={[31.432026740690574, 120.8439179532812]}
zoom={8}
>
<TileLayer
// those two url are the same i just add both in case one of them get out of service
url="https://maponline{s}.bdimg.com/onlinelabel/?qt=tile&x={x}&y={y}&z={z}&styles=pl"
//url="http://online{s}.map.bdimg.com/onlinelabel/?qt=tile&x={x}&y={y}&z={z}&styles=pl&scaler=1&p=1"
subdomains={["0", "1", "2", "3"]}
maxNativeZoom={18}
minNativeZoom={3}
tms
/>
</MapContainer>
</div>
);
}
export default App;
And now congratulations, π₯³π₯³ that's it.
In the application that Iβm working on, I use Baidu for china and google for other countries by just replacing the tile and removing the crs prop from MapContainer. I explained how to do it in a previous article.
Top comments (0)