The project show a map with markers on historical heritage places of Herault, a south of France territory.
The user can click on marker to display a pic coming from Flickr taken around that place. He also can show a sidebar with a text input and a list of the places.
The list and the markers are shown in accordance of the places matching the query.
The project is responsive and usable on modern device and it passes aXe accessiblity audit except 3 issues in Google map iframe where no corrective action can be taken.
A service worker is installed and a offline-first rendering is used allowing an offline use.
To run the project you need an ES5 compliant browser
To install the project you will need npm, visit npm page to install it if needed.
The project is created with create-ract-app so all dependencies will be added.
-
Clone the repository or download the files
-
Go to the directory where you have cloned or copied the project and run:
npm install
The project will install all dependencies requested. -
run
npm start
to start the application. A web page will open in your browser with the home page of the application. By default the server runs on port 3000.
If this port is used on your computer you can change it by setting another port in the package.json file:- Linux:
"start": "PORT=XXXX react-scripts start"
- Windows:
"start": "set PORT=XXXX && react-scripts start"
where XXXX is the port you want
- Linux:
Or just use the live app here.
- prop-types
- sort-by
- react-router-dom
- escape-string-regexp
- sort-by
- recompose
- react-google-map (follow this link for documentation)
The home page display a full screen map of the french territory of Herault. Markers are historical hetitages places comming from the french opendata project Merimée. The User can then get pictures taken around this places.
Photos are fetched with the Flickr API. They sometimes may not be relevant despite the sort made on Flickr's search. It relies only on how the photo was documented by the user of Flickr. The search is made in french to get as many results as possible and with the followong criteria to be as relevent as possible:
- Localisation (latidude and longitude)
- free text search using the french title of the place. generic terms like hotel, house, etc... are replaced with monument for more relevance.
- public tag true
- isfriend tag false
- isfamily tag false
See Flicker's API documentation for more details).
The number of markers is quite big (more than 3 hundred), in order to help the user he can search for specifics kind of monuments or places. He can open a search menu by clicking on the hamburger menu icon to slide a search menu in.
On this menu, he will find a text search input and a list of places. He can filter the places listed by entering a query in the search input when he does so the list and the markers are filtered according to the query.
User can see the photos by:
- Clicking on a marker: An info window opens in the map showing the first pic if any. The map is zoomed to a closer view of the placed cliked and centered on it.If the sidebar search menu is open, the list of places is scrolled to have this place on top of the part of the list which is diplayed, the first pic is shown under this link with a link to see more photos if any.
- Clicking on an item in the list in the side bar menu if it is open. This action have the same effect as clicking on a marker and the info window in the map is opened too.
Clicking on the "more photos" link when available leads to a new page with up to 9 photos (depending on what is found on Flickr).
When the user comes back to the home page query, and selected place are reset.
- V 0.9 05/13/2018 Submission of project
The poject uses 9 components
-
App: Main page of the application showing the map and the sidebap menu when hamburger button is clicked
- state:
- pointsOfInterest: array
- searchedPoints: array
- selectedId: number
- mouseOverId: number
- mapCenter: objet
- pics: array
- query: string
- props: none
- Route: "/"
- state:
-
Footer: detailed information of the selected book
- state: none
- props: none
- Route: inherited from the parent App ("/") or PicsPage ("/pics").
-
Header: detailed information of the selected book
- state: none
- props: none
- Route: inherited from the parent App ("/") or PicsPage ("/pics").
-
ListPlaces: list all the places matching the query
- state: none
- props:
- places : array
- listElementClicked: function (callback function when an element of the list is clicked)
- selectedId: number
- Route: - Route: no specific route inherited from App ('/').
-
MyMap: display a map using Google map Api
- state: none
- props:
- mapCenter: objet
- placesOfInterest: array
- selectedId: number
- pics: array
- mouseOverId: number
- markerClicked: number
- markerOver: function
- markerOut: function
- infoBoxClosed: function
- Route: no specific route inherited from App ('/').
-
PicsPage: display up to 9 pics coming from Flickr.
-
state : none
-
props:
- selectedId: number
- searchedPoints: array
- pics: array
-
Route: /pics specific route, inerited by the caller.
-
-
SearchPlace: the search input of the application
-
state: none
-
props:
- updateQuery: function
- query: string
- ariaHidden: boolean
-
Route: no specific route inherited from App ('/').
-
-
ShowPlace:
- state: none
- props:
- pics: array
- Route: no specific route inherited from App ('/') or PicsPage (/pics).
-
SideBar:
-
state:
- menuOn: boolean
-
props:
- places: array
- pics: array
- listElementClicked: function
- updateQuery: function
- query: string
- selectedId: number
-
Route: no specific route inherited from App ('/').
-
FilckrAPI.js is a file of util asynchronous functions used to call the Flickr API:
- searchPicsByPosition: receive an object describing a point of interest and return an array containing the first page of public photos around its position.
- getPics: recieve an array of search results and a number max of photos wanted and return an array of blobs.
- getBlob: recieve an url and return the blob located at this url.
Check Flickers API documentation for details.
P8-Neighborhood/
build/
node_module/
public/
icons/
favicon.ico
image-loading.png
monument-historique-hover.png
monument-historique-selected.png
monument-historique.png
no_pic.jpg
images/
neighborhood.jpg
favicon.ico
index.html
manifest.json
src/
components/
App.js
Footer.js
Header.js
ListPlaces.js
MyMap.js
PicsPage.js
SearchPlace.js
SideBar.js
data/
MapStyle.json
places.json
translation.json
icons/
add.swg
arrow-back.svg
hamburger.png
styles
app.css
utils
FlickrAPI.js
Apptest.js
index.css
index.js
logo.svg
registerMyServiceWorker.js
.eslintrc.js
.gitignore
package-lock.json
package.json
README.md
- React framework (see homepage)
- Maps: provided by GoogleMaps API
- Historical Heritage places: Wikipedia and Mérimée open data project from the french government. (Conversion to json and translation made by the author)
- Photos: public photos from the Flickr API
- Markers icons: Maps Icons Collection
- Alain Cadenat
Contributions to enhance the project are welcome
MIT License
Copyright (c) 2018 Alain CADENAT
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.