Skip to content

Instantly share code, notes, and snippets.

@McCulloughRT
Created November 13, 2018 19:54
Show Gist options
  • Save McCulloughRT/f280f31ba2afb8b087a9727a2f76efb2 to your computer and use it in GitHub Desktop.
Save McCulloughRT/f280f31ba2afb8b087a9727a2f76efb2 to your computer and use it in GitHub Desktop.
/* global mapboxgl */
import React, { Component } from 'react';
import './styles/reactmap.css';
export default class ReactMap extends Component {
constructor(props) {
super(props);
this.state = { loaded: false };
this.projectImage = this.projectImage.bind(this);
this.unprojectCoords = this.unprojectCoords.bind(this);
}
unprojectCoords(top, bottom, left, right) {
const upLeft = this.map.unproject([left, top]);
const upRight = this.map.unproject([right, top]);
const downRight = this.map.unproject([right, bottom]);
const downLeft = this.map.unproject([left, bottom]);
return { upLeft, upRight, downRight, downLeft };
}
projectImage(imgSize) {
const uL = this.map.project([-180, 85]);
const uR = this.map.project([180, 85]);
const lR = this.map.project([180, -85]);
const lL = this.map.project([-180,-85]);
const mapSize = { x: lR.y - uR.y, y: uR.x - uL.x };
// fit image width to map width and scale height
let scaledImgX = mapSize.x;
let scaledImgY = (imgSize.y * mapSize.x) / imgSize.x;
if(scaledImgY > mapSize.y) {
// the scaled image is the wrong ratio
// fit image height to map height and scale width;
scaledImgY = mapSize.y;
scaledImgX = (imgSize.x * mapSize.y) / imgSize.y;
const xLeftOver = mapSize.x - scaledImgX;
const xPosLeft = Math.floor(xLeftOver / 2);
const xPosRight = Math.floor(xPosLeft + scaledImgX);
const coords = this.unprojectCoords(uL.y, lR.y, xPosLeft, xPosRight);
return coords;
} else {
// scaled image is the correct proportion
const yLeftOver = mapSize.y - scaledImgY;
const yPosTop = Math.floor(yLeftOver / 2);
const yPosBtm = Math.floor(yPosTop + scaledImgY);
const coords = this.unprojectCoords(yPosTop, yPosBtm, uL.x, uR.x);
return coords;
}
}
componentDidMount() {
console.log('component mounted!');
const { container, img, imgHeight, imgWidth, returnFn } = this.props;
const mapConfig = {
container: container,
zoom: 0,
renderWorldCopies: false
};
mapboxgl.accessToken = MAPBOX_TOKEN;
this.map = new mapboxgl.Map(mapConfig);
const { upLeft, upRight, downRight, downLeft } = this.projectImage({ x:imgWidth, y:imgHeight });
const ddStyle = {
"version": 8,
"sources": {
"overlay": {
"type": "image",
"url": img,
"coordinates": [
[upLeft.lng, upLeft.lat],
[upRight.lng, upRight.lat],
[downRight.lng, downRight.lat],
[downLeft.lng, downLeft.lat]
]
}
},
"layers": [
{
"id": "overlay",
"source": "overlay",
"type": "raster",
"paint": {"raster-opacity": 1}
}
]
};
this.map.setStyle(ddStyle);
if(returnFn) returnFn( this.map );
this.setState({loaded: true});
}
componentWillUnmount() {
console.log('removing map');
this.map.remove();
}
render() {
const { container, img, imgHeight, imgWidth, returnFn } = this.props;
if(this.state.loaded){
this.map.resize();
}
return (
<div id={ container } className='map'></div>
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment