Skip to content
Snippets Groups Projects
AppleMaps.js 7.14 KiB
Newer Older
tonyduanesmith's avatar
tonyduanesmith committed
import React, { Component } from 'react'

class AppleMaps extends Component {
tonyduanesmith's avatar
tonyduanesmith committed
	componentDidMount() {
		const { token, children, initialMapType } = this.props
tonyduanesmith's avatar
tonyduanesmith committed
		this.canvas = document.createElement('canvas')
		this.canvas.id = 'currentLocationOverride'
tonyduanesmith's avatar
tonyduanesmith committed
		mapkit.init({
			authorizationCallback: function(done) {
				done(token)
			}
		})

		this.map = new mapkit.Map('map')
		// Set initial mapType
		if(initialMapType !== undefined) {
			this.map.mapType = initialMapType
		}

tonyduanesmith's avatar
tonyduanesmith committed
		if (children !== undefined && children.length) {
tonyduanesmith's avatar
tonyduanesmith committed
			children.forEach(child => {
				if (child.props.isAnnotation) {
tonyduanesmith's avatar
tonyduanesmith committed
				}
			})
tonyduanesmith's avatar
tonyduanesmith committed
		} else if (children !== undefined && children.props) {
			if (children.props.isAnnotation) {
tonyduanesmith's avatar
tonyduanesmith committed
		//	Image Annotations
		if (children !== undefined && children.length) {
			children.forEach(child => {
				if (child.props.isImageAnnotation) {
tonyduanesmith's avatar
tonyduanesmith committed
					this.createImageAnnotation(child.props)
				}
			})
		} else if (children !== undefined && children.props) {
			if (children.props.isImageAnnotation) {
tonyduanesmith's avatar
tonyduanesmith committed
				this.createImageAnnotation(children.props)
			}
		}

		// Current Location Override
		if (children !== undefined && children.length) {
tonyduanesmith's avatar
tonyduanesmith committed
			children.forEach(child => {
tonyduanesmith's avatar
tonyduanesmith committed
				if (child.type.name === 'CurrentLocationOverride') {
					this.createCurrentLocationOverride(child.props)
tonyduanesmith's avatar
tonyduanesmith committed
				}
			})
		} else if (children !== undefined && children.props) {
tonyduanesmith's avatar
tonyduanesmith committed
			if (children.type.name === 'CurrentLocationOverride') {
				this.createCurrentLocationOverride(children.props)
			}
tonyduanesmith's avatar
tonyduanesmith committed
		}
tonyduanesmith's avatar
tonyduanesmith committed
	componentDidUpdate(prevProps) {
		const {
			children,
			latitude,
			longitude,
			spanLat,
			spanLong,
			prevProps.latitude !== latitude ||
			prevProps.longitude !== longitude ||
			prevProps.spanLat !== spanLat ||
			prevProps.spanLong !== spanLong ||
			prevProps.zoomLevel !== zoomLevel ||
			prevProps.width !== width ||
			prevProps.height !== height ||
			prevProps.autoAdjust !== autoAdjust
		) && autoAdjust) {
			this.setMainCoords()
		}

		if (children !== undefined && children.length) {
			children.forEach(child => {
				if (child.props.isAnnotation) {
					this.updateAnnotation(child.props)
				}
			})
		} else if (children !== undefined && children.props) {
			if (children.props.isAnnotation) {
				this.updateAnnotation(children.props)
			}
		}

		let checkCurrentLocationLatitudeChange, checkCurrentLocationLongitudeChange, checkCurrentLocationDirectionChange
tonyduanesmith's avatar
tonyduanesmith committed
		if (typeof children !== 'undefined') {
			const firstChild = children[0] ? children[0] : children;
			const prevFirstChild = prevProps.children[0] ? prevProps.children[0] : prevProps.children;
				firstChild.props.latitude !==
				prevFirstChild.props.latitude
			checkCurrentLocationLongitudeChange =
				firstChild.props.longitude !==
				prevFirstChild.props.longitude
			checkCurrentLocationDirectionChange =
				firstChild.props.direction !==
				prevFirstChild.props.direction
			checkCurrentLocationLatitudeChange ||
			checkCurrentLocationLongitudeChange ||
			checkCurrentLocationDirectionChange
tonyduanesmith's avatar
tonyduanesmith committed
		) {
			if (children !== undefined && children.length) {
				children.forEach(child => {
tonyduanesmith's avatar
tonyduanesmith committed
					if (child.type.name === 'CurrentLocationOverride') {
						this.updateCurrentLocationOverride(child.props)
					}
				})
			} else if (children !== undefined && children.props) {
tonyduanesmith's avatar
tonyduanesmith committed
				if (children.type.name === 'CurrentLocationOverride') {
					this.updateCurrentLocationOverride(children.props)
tonyduanesmith's avatar
tonyduanesmith committed
	createAnnotation(annotationOptions) {
tonyduanesmith's avatar
tonyduanesmith committed
			glyphImage,
			subtitle,
			visible
		let MarkerAnnotation = mapkit.MarkerAnnotation
		let coords = new mapkit.Coordinate(latitude, longitude)
tonyduanesmith's avatar
tonyduanesmith committed
		let newAnnotation = new MarkerAnnotation(coords, {
			color,
			title,
			subtitle,
			selected,
			visible
tonyduanesmith's avatar
tonyduanesmith committed
		})
		glyphText ? (newAnnotation.glyphText = glyphText) : ''
tonyduanesmith's avatar
tonyduanesmith committed
		glyphImage ? (newAnnotation.glyphImage = { 1: glyphImage }) : ''
		if(id) {
			this.annotations[id] = newAnnotation;
		} else {
			console.warn("Apple MapKitJS annotation created without id prop!");
		}
tonyduanesmith's avatar
tonyduanesmith committed
		this.map.showItems([newAnnotation])
	}

	updateAnnotation(annotationOptions) {
		const {
			id,
			latitude,
			longitude
		} = annotationOptions

		if(id === undefined) {
			return
		}

		if(!(id in this.annotations)) {
			this.createAnnotation(annotationOptions)
			return
		}
		let annotation = this.annotations[id];
		if(latitude !== annotation.coordinate.latitude || longitude !== annotation.coordinate.longitude) {
			annotation.coordinate = new mapkit.Coordinate(latitude, longitude)
		}
	}

tonyduanesmith's avatar
tonyduanesmith committed
	createImageAnnotation(annotationOptions) {
		const {
			longitude,
			latitude,
			url,
			selected,
			title,
			subtitle,
			visible
tonyduanesmith's avatar
tonyduanesmith committed
		} = annotationOptions
		let ImageAnnotation = mapkit.ImageAnnotation
		let coords = new mapkit.Coordinate(latitude, longitude)
tonyduanesmith's avatar
tonyduanesmith committed
		let newAnnotation = new ImageAnnotation(coords, {
			title,
			subtitle,
			selected,
tonyduanesmith's avatar
tonyduanesmith committed
			url: { 1: url }
		})
	createCurrentLocationOverride(locationOptions) {
		const { longitude, latitude, direction } = locationOptions
		// AppleMaps needs options structured this way
		const options = {
			data: {
				direction: direction
			}
		}
		const coordinate = new mapkit.Coordinate(latitude, longitude)
		this.currentLocation = new mapkit.Annotation(
tonyduanesmith's avatar
tonyduanesmith committed
				let ctx = this.canvas.getContext('2d')
				ctx.beginPath()
				ctx.translate(150, 135)
				ctx.rotate((options.data.direction * Math.PI) / 180)
				ctx.lineCap = 'round'
				ctx.moveTo(0, 7)
				ctx.lineTo(10, 12)
				ctx.lineTo(0, -13)
				ctx.lineTo(-10, 12)
				ctx.lineTo(0, 7)
				ctx.fillStyle = '#08F'
				ctx.strokeStyle = '#08F'
				ctx.stroke()
				ctx.fill()
tonyduanesmith's avatar
tonyduanesmith committed
				return this.canvas
		this.map.showItems([this.currentLocation])
	}

	updateCurrentLocationOverride(locationOptions) {
		const { longitude, latitude } = locationOptions
		const coordinate = new mapkit.Coordinate(latitude, longitude)
		this.currentLocation.coordinate = coordinate
tonyduanesmith's avatar
tonyduanesmith committed
	setMainCoords() {
		const { longitude, latitude, spanLat, spanLong } = this.props
		this.map.region = new mapkit.CoordinateRegion(
			new mapkit.Coordinate(latitude, longitude),
			new mapkit.CoordinateSpan(spanLat ? spanLat : this.zoomLevel(), spanLong ? spanLong : this.zoomLevel())
tonyduanesmith's avatar
tonyduanesmith committed
	zoomLevel() {
		const { zoomLevel } = this.props
tonyduanesmith's avatar
tonyduanesmith committed
		switch (zoomLevel) {
			case 0:
				return 300
			case 1:
				return 75
			case 2:
				return 18.75
			case 3:
				return 4.68
			case 4:
				return 1.17
			case 5:
				return 0.39
			case 6:
				return 0.073
			case 7:
				return 0.018
			case 8:
				return 0.0045
			default:
				return 0.35
		}
	}

tonyduanesmith's avatar
tonyduanesmith committed
	render() {
		const { width, height } = this.props
tonyduanesmith's avatar
tonyduanesmith committed
		return (
			<div
				id='map'
tonyduanesmith's avatar
tonyduanesmith committed
					width: width,
}

AppleMaps.defaultProps = {
	width: '100wh',
	height: '100vh',
tonyduanesmith's avatar
tonyduanesmith committed
	zoomLevel: 6,
	longitude: 53.8008,
	latitude: -1.5491,
	autoAdjust: false
tonyduanesmith's avatar
tonyduanesmith committed
export default AppleMaps