Skip to content

Commit

Permalink
Merge pull request #178 from damianmoore/map-photo-clustering#14
Browse files Browse the repository at this point in the history
[Feature] 14: Map photo clustering and filtering according to pan and zoom
  • Loading branch information
damianmoore committed Jan 30, 2021
2 parents daa01ef + 118877a commit ff76155
Show file tree
Hide file tree
Showing 10 changed files with 196 additions and 190 deletions.
4 changes: 3 additions & 1 deletion ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,16 @@
"history": "^4.10.1",
"js-cookie": "^2.2.1",
"leaflet": "^1.6.0",
"leaflet.markercluster": "^1.4.1",
"little-state-machine": "^2.14.1",
"normalize.css": "^8.0.1",
"react": "^16.13.0",
"react-compound-slider": "3.3.1",
"react-dom": "^16.13.0",
"react-hook-form": "^5.6.0",
"react-lazy-load-image-component": "^1.5.1",
"react-leaflet": "^2.6.1",
"react-leaflet": "^3.0.5",
"react-leaflet-markercluster": "^3.0.0-rc1",
"react-redux": "^7.2.2",
"react-router-dom": "^5.1.2",
"react-router-modal": "^1.5.2",
Expand Down
18 changes: 8 additions & 10 deletions ui/public/index.html
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.png">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<link rel='stylesheet' href='%PUBLIC_URL%/thirdparty/leaflet/leaflet.css'>
<meta charset="utf-8" />
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<meta name="theme-color" content="#000000" />
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<link rel='stylesheet' href='%PUBLIC_URL%/thirdparty/leaflet/leaflet.css' />
<title>Photonix Photo Manager</title>
<meta content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0' name='viewport' />
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
<!--# include file="extra_head.html" -->
</head>
<body style="background: #1d1d1d">
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--# include file="extra_body.html" -->
</body>
Expand Down
Binary file modified ui/public/thirdparty/leaflet/images/marker-icon-2x.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified ui/public/thirdparty/leaflet/images/marker-icon.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 3 additions & 3 deletions ui/src/components/Browse.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Link } from 'react-router-dom'
import Header from './Header'
import SearchContainer from '../containers/SearchContainer'
import PhotoListContainer from '../containers/PhotoListContainer'
import MapViewContainer from '../containers/MapViewContainer'
import MapView from '../components/MapView'
import Spinner from '../components/Spinner'
import arrowDown from '../static/images/arrow_down.svg'
import '../static/css/Browse.css'
Expand All @@ -21,11 +21,11 @@ const Browse = ({
onExpandCollapse,
expanded,
search,
updateSearchText
updateSearchText,
}) => {
let content =
mode === 'MAP' ? (
<MapViewContainer photos={photoSections[0].segments[0].photos} />
<MapView photos={photoSections[0].segments[0].photos} />
) : (
<PhotoListContainer
selectedFilters={selectedFilters}
Expand Down
55 changes: 31 additions & 24 deletions ui/src/components/ComponentsBrowser.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import React from 'react'

import FiltersContainer from '../containers/FiltersContainer'
import MapViewContainer from '../containers/MapViewContainer'
import MapView from '../components/MapView'
import PhotoListContainer from '../containers/PhotoListContainer'
import '../static/css/ComponentsBrowser.css'


const generateId = () => (
Math.floor(Math.random() * 100000)
)
const generateId = () => Math.floor(Math.random() * 100000)

const randomImage = () => {
let images = [
Expand All @@ -23,28 +20,38 @@ const randomImage = () => {

const randomLocation = () => {
let locations = [
["64.039132", "-16.173093"],
["64.150117", "-21.933912"],
['64.039132', '-16.173093'],
['64.150117', '-21.933912'],
]
return locations[Math.floor(Math.random() * locations.length)]
}


const ComponentsBrowser = () => {
let photos = []
for (var i=0; i < 100; i++) {
photos.push(
{
id: generateId(),
location: randomLocation(),
thumbnail: randomImage()
},
)
for (var i = 0; i < 100; i++) {
photos.push({
id: generateId(),
location: randomLocation(),
thumbnail: randomImage(),
})
}

let photoSections = []

let months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
let months = [
'Jan',
'Feb',
'Mar',
'Apr',
'May',
'Jun',
'Jul',
'Aug',
'Sep',
'Oct',
'Nov',
'Dec',
]
let years = ['2017', '2018']
years.reverse()
months.reverse()
Expand All @@ -58,7 +65,7 @@ const ComponentsBrowser = () => {
let photo = {
id: id,
location: [null, null],
thumbnail: randomImage()
thumbnail: randomImage(),
}
monthPhotos.push(photo)
}
Expand All @@ -68,9 +75,9 @@ const ComponentsBrowser = () => {
segments: [
{
numPhotos: monthPhotos.length,
photos: monthPhotos
}
]
photos: monthPhotos,
},
],
}
photoSections.push(section)
}
Expand Down Expand Up @@ -100,10 +107,10 @@ const ComponentsBrowser = () => {
</div>
</div>

<div className="preview MapViewContainerPreview">
<h2>MapViewContainer</h2>
<div className="preview MapViewPreview">
<h2>MapView</h2>
<div>
<MapViewContainer photos={photos} />
<MapView photos={photos} />
</div>
</div>
</div>
Expand Down
81 changes: 54 additions & 27 deletions ui/src/components/MapView.js
Original file line number Diff line number Diff line change
@@ -1,58 +1,85 @@
import React from 'react'
import PropTypes from 'prop-types'
import { Link } from 'react-router-dom'
import { Map, Marker, Popup, TileLayer } from 'react-leaflet'
import '../static/css/Map.css'
import { MapContainer, Marker, Popup, TileLayer } from 'react-leaflet'
import MarkerClusterGroup from 'react-leaflet-markercluster'

import '../static/css/Map.css'
import 'react-leaflet-markercluster/dist/styles.min.css' // sass

const MapView = ({ photos, bounds, location, zoom, hideAttribution }) => {
const MapView = ({
photos,
bounds,
location,
zoom,
maxZoom,
hideAttribution,
}) => {
let markers = []
let tileUrl = 'https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png'
let attribution = hideAttribution ? '' : '&copy; <a href=&quot;http://osm.org/copyright&quot;>OpenStreetMap</a> contributors'
let attribution = hideAttribution
? ''
: '&copy; <a href=&quot;http://osm.org/copyright&quot;>OpenStreetMap</a> contributors'
let tileLayer = <TileLayer attribution={attribution} url={tileUrl} />

if (photos) {
markers = photos.map((photo, idx) => (
photo.location ?
markers = photos.map((photo, idx) =>
photo.location ? (
<Marker
key={`marker-${photo.id}`}
position={[photo.location[0], photo.location[1]]}>
position={[photo.location[0], photo.location[1]]}
>
<Popup>
<Link to={'/photo/' + photo.id} key={photo.id}>
<img src={photo.thumbnail} style={{ width: 128, height: 128 }} alt="marker popup" />
<img
src={photo.thumbnail}
style={{ width: 128, height: 128 }}
alt="marker popup"
/>
</Link>
</Popup>
</Marker>
:
null
))

) : null
)
return (
<div className="Map">
<Map bounds={bounds} boundsOptions={{padding: [100, 100], maxZoom: 15}}>
<MapContainer
bounds={bounds}
boundsOptions={{ padding: [100, 100], maxZoom: maxZoom }}
zoom={zoom}
center={[30, 0]}
>
{tileLayer}
{markers}
</Map>
<MarkerClusterGroup>{markers}</MarkerClusterGroup>
</MapContainer>
</div>
)
}

else if (location) {
markers = [
<Marker
key='marker'
position={location}>
</Marker>
]
} else if (location) {
markers = [<Marker key="marker" position={location}></Marker>]

return (
<div className="Map">
<Map center={location} zoom={zoom} zoomControl={true}>
<MapContainer center={location} zoom={zoom} zoomControl={true}>
{tileLayer}
{markers}
</Map>
<MarkerClusterGroup>{markers}</MarkerClusterGroup>
</MapContainer>
</div>
)
}
}

MapView.propTypes = {
photos: PropTypes.string,
bounds: PropTypes.func,
location: PropTypes.array,
zoom: PropTypes.number,
maxZoom: PropTypes.number,
hideAttribution: PropTypes.bool,
}

MapView.defaultProps = {
zoom: 2,
maxZoom: 15,
}

export default MapView

0 comments on commit ff76155

Please sign in to comment.