fix: mobile layout
@ -56,6 +56,7 @@ http {
|
||||
|
||||
location ~ /tiles/(?<fwd_path>.*) {
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-Proto "https";
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Host $host;
|
||||
|
@ -1,80 +1,33 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import React from 'react';
|
||||
|
||||
import 'normalize.css';
|
||||
import GlobalStyle from './GlobalStyle';
|
||||
import './index.css';
|
||||
import octocat from './kotik.svg';
|
||||
import urbica from './urbica-logo.svg';
|
||||
import arrowurbica from './arrow_urbica.svg';
|
||||
|
||||
import Map from '../Map';
|
||||
import Intro from '../Intro';
|
||||
import Description from '../Description';
|
||||
import Features from '../Fatures';
|
||||
import TryIt from '../TryIt';
|
||||
import Map from '../Map';
|
||||
import Development from '../Development/Development';
|
||||
import Footer from '../Footer/Footer';
|
||||
|
||||
class App extends PureComponent {
|
||||
render() {
|
||||
return (
|
||||
<>
|
||||
<GlobalStyle />
|
||||
<Intro />
|
||||
<Description />
|
||||
<div className='martin_items'>
|
||||
<div className='feature'>
|
||||
<h1 className='feature-description'>
|
||||
Turning Data into Vector Tiles
|
||||
</h1>
|
||||
<h2>
|
||||
Martin creates Mapbox Vector Tiles from any PostGIS table or view
|
||||
</h2>
|
||||
</div>
|
||||
<div className='feature'>
|
||||
<h1 className='feature-description'>
|
||||
Generating Tiles with Functions
|
||||
</h1>
|
||||
<h2>
|
||||
Martin is the only vector tile server capable of creating tiles
|
||||
using database functions directly
|
||||
</h2>
|
||||
</div>
|
||||
<div className='feature'>
|
||||
<h1 className='feature-description'>
|
||||
Filtering and Aggregating Data
|
||||
on the Fly
|
||||
</h1>
|
||||
<h2>
|
||||
Martin is ideal for large datasets as it allows passing
|
||||
parameters from a URL into a user function to filter features and
|
||||
aggregate attribute values
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div className='try-it'>
|
||||
This is a demo of how Martin works. We used 2017
|
||||
New York City taxi trips dataset: about 114 million records and a 13GB
|
||||
database. Martin uses a database function to filter the data by
|
||||
selected dates, days of the week, and hours and to sum or average the
|
||||
numbers by areas.
|
||||
</div>
|
||||
<Map />
|
||||
<div className='development'>
|
||||
<div>Start building with Martin!</div>
|
||||
<a href='https://github.com/urbica/martin' className='git-button'>
|
||||
View on Github
|
||||
<img src={octocat} alt='octocat' />
|
||||
</a>
|
||||
</div>
|
||||
<footer className='footer'>
|
||||
<div className='footerdescription'>MADE BY</div>
|
||||
<a href='https://urbica.co'>
|
||||
<img src={urbica} alt='urbica' />
|
||||
</a>
|
||||
<a href='https://urbica.co' className='footerarrow'>
|
||||
<img src={arrowurbica} alt='arrowurbica' />
|
||||
</a>
|
||||
</footer>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
const App = () => (
|
||||
<>
|
||||
<GlobalStyle />
|
||||
<Intro />
|
||||
<Description>
|
||||
Martin is an Open Source PostGIS vector tile server created by Urbica
|
||||
</Description>
|
||||
<Features />
|
||||
<TryIt>
|
||||
This is a demo of how Martin works. We used 2017 New York City taxi trips
|
||||
dataset: about 114 million records and a 13GB database. Martin uses a
|
||||
database function to filter the data by selected dates, days of the week,
|
||||
and hours and to sum or average the numbers by areas.
|
||||
</TryIt>
|
||||
<Map />
|
||||
<Development />
|
||||
<Footer />
|
||||
</>
|
||||
);
|
||||
|
||||
export default App;
|
||||
|
@ -1,14 +1,13 @@
|
||||
/* eslint-disable max-len */
|
||||
import { createGlobalStyle } from 'styled-components';
|
||||
import 'normalize.css';
|
||||
|
||||
// vremenaGroteskBook
|
||||
import vremenaGroteskBook from './assets/fonts/VremenaGroteskBook.otf';
|
||||
import vremenaGroteskBookWoff2 from './assets/fonts/VremenaGroteskBookWoff2.woff2';
|
||||
// vremenagroteskBook
|
||||
import vremenagroteskbookWoff2 from './fonts/vremenagroteskbook.woff2';
|
||||
import vremenagroteskbookWoff from './fonts/vremenagroteskbook.woff';
|
||||
|
||||
// vremenaGroteskBold
|
||||
import vremenaGroteskBold from './assets/fonts/VremenaGroteskBold.otf';
|
||||
import vremenaGroteskBoldWoff2 from './assets/fonts/VremenaGroteskBoldWoff2.woff2';
|
||||
|
||||
import vremenagroteskboldWoff2 from './fonts/vremenagroteskbold.woff2';
|
||||
import vremenagroteskboldWoff from './fonts/vremenagroteskbold.woff';
|
||||
|
||||
export default createGlobalStyle`
|
||||
* {
|
||||
@ -16,31 +15,28 @@ export default createGlobalStyle`
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: VremenaGroteskBook;
|
||||
src:
|
||||
url(${vremenaGroteskBook}) format('otf'),
|
||||
url(${vremenaGroteskBookWoff2}) format('woff2');
|
||||
font-family: vremena;
|
||||
src: url(${vremenagroteskbookWoff2}) format('woff2'),
|
||||
url(${vremenagroteskbookWoff}) format('woff');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: VremenaGroteskBold;
|
||||
src:
|
||||
url(${vremenaGroteskBold}) format('otf'),
|
||||
url(${vremenaGroteskBoldWoff2}) format('woff2');
|
||||
font-family: vremena;
|
||||
src: url(${vremenagroteskboldWoff2}) format('woff2'),
|
||||
url(${vremenagroteskboldWoff}) format('woff');
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
body {
|
||||
background-image: linear-gradient(to bottom, #0e0e1e 50%, #1c1c30);
|
||||
font-family: VremenaGroteskBook, sans-serif;
|
||||
font-family: vremena, sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
|
||||
color: white;
|
||||
|
||||
h1 {
|
||||
font-family: VremenaGroteskBold, sans-serif;
|
||||
background-image: linear-gradient(to bottom, #0e0e1e 50%, #1c1c30);
|
||||
}
|
||||
`;
|
||||
|
@ -1,15 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="535px" height="90px" viewBox="0 0 535 90" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 52.2 (67145) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>MARTIN</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" fill-opacity="0" font-family="VremenaGroteskBold, Vremena Grotesk" font-size="120" font-weight="bold" letter-spacing="12" line-spacing="100">
|
||||
<g id="screen_new_4" transform="translate(-741.000000, -261.000000)" fill="#FFFFFF" stroke="#FFFFFF">
|
||||
<g id="1" transform="translate(-305.000000, -21.000000)">
|
||||
<text id="MARTIN">
|
||||
<tspan x="1039" y="379">MARTIN</tspan>
|
||||
</text>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 900 B |
@ -1,26 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="90px" height="12px" viewBox="0 0 118 22" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 52.2 (67145) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>Urbica_logo</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="screen_new_2" transform="translate(-689.000000, -4447.000000)" fill="#FFFFFF">
|
||||
<g id="4" transform="translate(0.000000, 3600.000000)">
|
||||
<g id="Footer" transform="translate(0.000000, 814.000000)">
|
||||
<g id="Group" transform="translate(593.000000, 33.000000)">
|
||||
<g id="Urbica_logo" transform="translate(96.000000, 0.000000)">
|
||||
<g id="Urbica">
|
||||
<polygon id="Fill-1" points="68.2359718 22 72.1351702 22 72.1351702 0 68.2359718 0"></polygon>
|
||||
<path d="M107.436189,0 L99.4295589,22 L102.877808,22 L105.144959,15.6108164 L112.236618,15.6108164 L114.503769,22 L117.950751,22 L109.944122,0 L107.436189,0 Z M108.690789,5.30592712 L111.131556,12.4219327 L106.247487,12.4219327 L108.690789,5.30592712 Z" id="Fill-2"></path>
|
||||
<polygon id="Fill-3" points="82.9712048 0 77.0091682 5.7870034 77.0091682 16.206654 82.9751246 22 90.4070914 22 94.5555609 17.9724384 92.219352 15.7043187 89.0377698 18.7957101 84.341833 18.7957101 80.3109579 14.8797786 80.3109579 7.11768437 84.341833 3.20302139 89.0377698 3.20302139 92.219352 6.29060716 94.5555609 4.02375598 90.4097046 0"></polygon>
|
||||
<path d="M46.7903807,0 L46.7903807,22 L57.6555189,22 L62.3871742,17.3766369 L62.3871742,13.1162388 L59.2769098,10.0792616 L61.598565,7.81136429 L61.598565,4.04718777 L57.4268612,0 L46.7903807,0 Z M50.1202084,3.21084511 L56.0964891,3.21084511 L58.3155082,5.37594462 L58.3155082,6.48387655 L56.0341279,8.7124315 L50.1202084,8.7124315 L50.1202084,3.21084511 Z M50.1202084,11.9321604 L56.5317183,11.9321604 L59.1093141,14.448803 L59.1093141,16.0440727 L56.3108557,18.7764638 L50.1202084,18.7802711 L50.1202084,11.9321604 Z" id="Fill-4"></path>
|
||||
<path d="M24.3699899,0 L24.3699899,22 L27.5867815,22 L27.5867815,13.1581194 L32.5990501,13.1581194 L36.4097302,22 L39.9667835,22 L35.9413995,12.8319585 L39.9529721,8.7568503 L39.9529721,4.3124315 L35.6852615,0 L24.3699899,0 Z M27.5867815,3.21084511 L34.3756933,3.21084511 L36.7813814,5.64245746 L36.7813814,7.4496683 L34.3217035,9.93585232 L27.5867815,9.93585232 L27.5867815,3.21084511 Z" id="Fill-5"></path>
|
||||
<polygon id="Fill-6" points="13.3394414 0 13.3394414 16.04682 10.6816972 18.76146 10.6804292 18.76146 5.88989595 18.76146 3.23215173 16.04682 3.23215173 0 0 0 0 17.3800381 4.61681618 22 6.30199847 22 11.953509 22 16.5715932 17.3800381 16.5715932 0"></polygon>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 3.1 KiB |
BIN
frontend/src/Components/App/assets/fonts/VremenaGroteskBoldWoff.woff → frontend/src/Components/App/fonts/vremenagroteskbold.woff
Normal file → Executable file
BIN
frontend/src/Components/App/fonts/vremenagroteskbold.woff2
Executable file
BIN
frontend/src/Components/App/fonts/vremenagroteskbook.woff
Executable file
BIN
frontend/src/Components/App/fonts/vremenagroteskbook.woff2
Executable file
@ -1,121 +0,0 @@
|
||||
|
||||
.martin_items {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100vw;
|
||||
}
|
||||
|
||||
.feature {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-grow: inherit;
|
||||
margin: 150px 0 100px 40vh;
|
||||
border: 7px solid #7300FF;
|
||||
width: 400px;
|
||||
height: 450px;
|
||||
}
|
||||
|
||||
.feature:nth-child(2) {
|
||||
margin: 150px 0 100px 80vh;
|
||||
}
|
||||
|
||||
|
||||
.feature-description{
|
||||
display: flex;
|
||||
transform: translate(-125px, -80px);
|
||||
margin: 0;
|
||||
font-size: 45px;
|
||||
line-height: 55px;
|
||||
font-weight: bold;
|
||||
color: rgba(0,0,0,0);
|
||||
-webkit-text-stroke-width: 1px;
|
||||
-webkit-text-stroke-color: white;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
h2{
|
||||
display: flex;
|
||||
width: 40vw;
|
||||
padding: 0;
|
||||
margin: 0px;
|
||||
font-size: 35px;
|
||||
line-height: 45px;
|
||||
color: #ffffff;
|
||||
font-weight: normal;
|
||||
transform: translate(80px, 0px);
|
||||
}
|
||||
|
||||
.try-it {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin: 120px 100px 40px 100px;
|
||||
|
||||
font-size: 30px;
|
||||
font-weight: normal;
|
||||
line-height: 40px;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.map {
|
||||
display: flex;
|
||||
height: 600px;
|
||||
background-color: #7300FF;
|
||||
}
|
||||
|
||||
|
||||
.development {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: 120px 100px;
|
||||
font-size: 30px;
|
||||
font-weight: normal;
|
||||
line-height: 40px;
|
||||
color: white;
|
||||
}
|
||||
|
||||
|
||||
.git-button{
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items:center;
|
||||
width: 200px;
|
||||
height: 50px;
|
||||
margin-top: 50px;
|
||||
padding: 10px 10px;
|
||||
font-size: 20px;
|
||||
font-weight: normal;
|
||||
background-color: rgba(0,0,0,0);
|
||||
border: solid 1px #ffffff;
|
||||
color: #ffffff;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.git-button:hover{
|
||||
background-color: #1C1C30;
|
||||
box-shadow: 3px 3px 0 rgba(115, 0, 255, 1);
|
||||
border-color: #1C1C30;
|
||||
}
|
||||
|
||||
.footer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
justify-content: flex-end;
|
||||
height: 70px;
|
||||
background-color: #171727;
|
||||
color: white;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.footerdescription {
|
||||
margin-top: 10px;
|
||||
padding: 6px;
|
||||
color: #9fa3b2;
|
||||
}
|
||||
|
||||
.footerarrow {
|
||||
padding: 4px 25px 0px 8px;
|
||||
}
|
||||
|
||||
|
@ -1,9 +0,0 @@
|
||||
const sizes = {
|
||||
more: 5000,
|
||||
giant: 2000,
|
||||
desktop: 1170,
|
||||
tablet: 768,
|
||||
phone: 450
|
||||
};
|
||||
|
||||
export default sizes;
|
15
frontend/src/Components/Description.js
Normal file
@ -0,0 +1,15 @@
|
||||
import styled from 'styled-components';
|
||||
|
||||
export default styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
max-width: 635px;
|
||||
height: 40vh;
|
||||
padding: 7vw;
|
||||
margin:auto;
|
||||
|
||||
font-size: 30px;
|
||||
line-height: 1.55;
|
||||
`;
|
@ -1,16 +0,0 @@
|
||||
import React from 'react';
|
||||
|
||||
import DescriptionBlock from './DescriptionStyle';
|
||||
|
||||
const Description = () => (
|
||||
<DescriptionBlock>
|
||||
Martin is an Open Source
|
||||
<br />
|
||||
PostGIS
|
||||
vector tile server
|
||||
<br />
|
||||
created by Urbica
|
||||
</DescriptionBlock>
|
||||
);
|
||||
|
||||
export default Description;
|
@ -1,14 +0,0 @@
|
||||
import styled from 'styled-components';
|
||||
|
||||
export default styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 600px;
|
||||
|
||||
margin: 0vh 7vh 0 7vh;
|
||||
line-height: 61px;
|
||||
font-size: 50px;
|
||||
font-weight: normal;
|
||||
color: white;
|
||||
`;
|
@ -1 +0,0 @@
|
||||
export { default } from './Description';
|
8
frontend/src/Components/Development/Container.js
Normal file
@ -0,0 +1,8 @@
|
||||
import styled from 'styled-components';
|
||||
|
||||
export default styled.div`
|
||||
padding: 7vw;
|
||||
|
||||
font-size: 30px;
|
||||
line-height: 40px;
|
||||
`;
|
14
frontend/src/Components/Development/Development.js
Normal file
@ -0,0 +1,14 @@
|
||||
import React from 'react';
|
||||
|
||||
import Container from './Container';
|
||||
import Title from './Title';
|
||||
import GitHubButton from '../GitHubButton';
|
||||
|
||||
const Development = () => (
|
||||
<Container>
|
||||
<Title>Start building with Martin!</Title>
|
||||
<GitHubButton />
|
||||
</Container>
|
||||
);
|
||||
|
||||
export default Development;
|
5
frontend/src/Components/Development/Title.js
Normal file
@ -0,0 +1,5 @@
|
||||
import styled from 'styled-components';
|
||||
|
||||
export default styled.div`
|
||||
margin-bottom: 50px;
|
||||
`;
|
1
frontend/src/Components/Development/index.js
Normal file
@ -0,0 +1 @@
|
||||
export { default } from './Development';
|
11
frontend/src/Components/Fatures/Container.js
Normal file
@ -0,0 +1,11 @@
|
||||
import styled from 'styled-components';
|
||||
|
||||
export default styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
padding: 7vw;
|
||||
|
||||
overflow: hidden;
|
||||
`;
|
15
frontend/src/Components/Fatures/Description.js
Normal file
@ -0,0 +1,15 @@
|
||||
import styled from 'styled-components';
|
||||
|
||||
export default styled.div`
|
||||
position: relative;
|
||||
margin-left: 205px;
|
||||
|
||||
font-size: 35px;
|
||||
line-height: 45px;
|
||||
|
||||
@media (max-width: 500px) {
|
||||
margin-left: 20vw;
|
||||
|
||||
font-size: 30px;
|
||||
}
|
||||
`;
|
38
frontend/src/Components/Fatures/Feature.js
Normal file
@ -0,0 +1,38 @@
|
||||
import styled from 'styled-components';
|
||||
|
||||
export default styled.div`
|
||||
position: relative;
|
||||
|
||||
max-width: 710px;
|
||||
min-height: 544px;
|
||||
margin-right: 15vw;
|
||||
margin-bottom: 150px;
|
||||
|
||||
@media (max-width: 500px) {
|
||||
height: initial;
|
||||
margin-right: initial;
|
||||
}
|
||||
|
||||
&:before {
|
||||
content: '';
|
||||
|
||||
position: absolute;
|
||||
top: 80px;
|
||||
left: 125px;
|
||||
|
||||
width: 400px;
|
||||
height: 450px;
|
||||
|
||||
border: 7px solid #7300FF;
|
||||
|
||||
@media (max-width: 500px) {
|
||||
height: 380px;
|
||||
}
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
align-self: flex-end;
|
||||
|
||||
margin-right: initial;
|
||||
}
|
||||
`;
|
25
frontend/src/Components/Fatures/Features.jsx
Normal file
@ -0,0 +1,25 @@
|
||||
import React from 'react';
|
||||
|
||||
import martinFeatures from '../../config/features';
|
||||
|
||||
import Container from './Container';
|
||||
import Feature from './Feature';
|
||||
import Title from './Title';
|
||||
import Description from './Description';
|
||||
|
||||
const Features = () => (
|
||||
<Container>
|
||||
{martinFeatures.map(feature => (
|
||||
<Feature key={feature.id}>
|
||||
<Title>
|
||||
{feature.title}
|
||||
</Title>
|
||||
<Description>
|
||||
{feature.description}
|
||||
</Description>
|
||||
</Feature>
|
||||
))}
|
||||
</Container>
|
||||
);
|
||||
|
||||
export default Features;
|
19
frontend/src/Components/Fatures/Title.js
Normal file
@ -0,0 +1,19 @@
|
||||
import styled from 'styled-components';
|
||||
|
||||
export default styled.div`
|
||||
position: relative;
|
||||
max-width: 400px;
|
||||
margin-bottom: 80px;
|
||||
|
||||
font-size: 45px;
|
||||
font-weight: bold;
|
||||
color: transparent;
|
||||
line-height: 55px;
|
||||
-webkit-text-stroke-width: 1px;
|
||||
-webkit-text-stroke-color: white;
|
||||
text-transform: uppercase;
|
||||
|
||||
@media (max-width: 500px) {
|
||||
font-size: 35px;
|
||||
}
|
||||
`;
|
1
frontend/src/Components/Fatures/index.js
Normal file
@ -0,0 +1 @@
|
||||
export { default } from './Features';
|
13
frontend/src/Components/Footer/Container.js
Normal file
@ -0,0 +1,13 @@
|
||||
import styled from 'styled-components';
|
||||
|
||||
export default styled.footer`
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
justify-content: flex-end;
|
||||
|
||||
padding: 23px;
|
||||
|
||||
font-size: 16px;
|
||||
|
||||
background-color: #171727;
|
||||
`;
|
7
frontend/src/Components/Footer/Description.js
Normal file
@ -0,0 +1,7 @@
|
||||
import styled from 'styled-components';
|
||||
|
||||
export default styled.div`
|
||||
margin-right: 6px;
|
||||
|
||||
color: #9fa3b2;
|
||||
`;
|
21
frontend/src/Components/Footer/Footer.js
Normal file
@ -0,0 +1,21 @@
|
||||
import React from 'react';
|
||||
|
||||
import urbica from './urbica.svg';
|
||||
import arrow from './arrow.svg';
|
||||
|
||||
import Container from './Container';
|
||||
import Description from './Description';
|
||||
|
||||
const Footer = () => (
|
||||
<Container>
|
||||
<Description>
|
||||
MADE BY
|
||||
</Description>
|
||||
<a href='https://urbica.co'>
|
||||
<img src={urbica} alt='urbica' />
|
||||
<img src={arrow} alt='arrow' />
|
||||
</a>
|
||||
</Container>
|
||||
);
|
||||
|
||||
export default Footer;
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
1
frontend/src/Components/Footer/index.js
Normal file
@ -0,0 +1 @@
|
||||
export { default } from './Footer';
|
Before Width: | Height: | Size: 910 B After Width: | Height: | Size: 910 B |
24
frontend/src/Components/GitHubButton/Container.js
Normal file
@ -0,0 +1,24 @@
|
||||
import styled from 'styled-components';
|
||||
|
||||
export default styled.a`
|
||||
display: inline-flex;
|
||||
align-content: center;
|
||||
|
||||
padding: 10px;
|
||||
border: solid 1px #fff;
|
||||
font-size: 20px;
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
|
||||
cursor: pointer;
|
||||
|
||||
&:hover{
|
||||
background-color: #0E0E1E;
|
||||
box-shadow: 3px 3px 0 rgba(115, 0, 255, 1);
|
||||
border-color: #0E0E1E;
|
||||
}
|
||||
|
||||
img {
|
||||
margin-left: 10px;
|
||||
}
|
||||
`;
|
12
frontend/src/Components/GitHubButton/GitHubButton.js
Normal file
@ -0,0 +1,12 @@
|
||||
import React from 'react';
|
||||
import octocat from './octocat.svg';
|
||||
import Container from './Container';
|
||||
|
||||
const GitHubButton = () => (
|
||||
<Container href='https://github.com/urbica/martin'>
|
||||
<span>View on Github</span>
|
||||
<img src={octocat} alt='octocat' />
|
||||
</Container>
|
||||
);
|
||||
|
||||
export default GitHubButton;
|
1
frontend/src/Components/GitHubButton/index.js
Normal file
@ -0,0 +1 @@
|
||||
export { default } from './GitHubButton';
|
@ -1,3 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 34 34">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 28 26">
|
||||
<path fill="#ffffff" fill-rule="evenodd" d="M13.546 0c-7.18 0-13 5.968-13 13.33 0 5.888 3.724 10.885 8.89 12.647.65.123.888-.29.888-.641 0-.318-.012-1.368-.018-2.482-3.616.807-4.38-1.572-4.38-1.572-.59-1.541-1.443-1.95-1.443-1.95-1.18-.828.089-.811.089-.811 1.305.094 1.993 1.374 1.993 1.374 1.16 2.037 3.041 1.448 3.783 1.108.117-.862.453-1.45.825-1.783-2.887-.337-5.923-1.48-5.923-6.587 0-1.455.508-2.644 1.34-3.578-.135-.335-.58-1.691.126-3.527 0 0 1.091-.358 3.576 1.366a12.172 12.172 0 0 1 3.254-.448c1.104.005 2.217.153 3.256.448 2.482-1.724 3.572-1.366 3.572-1.366.707 1.836.262 3.192.127 3.527.834.934 1.338 2.123 1.338 3.578 0 5.12-3.041 6.247-5.936 6.577.466.413.882 1.224.882 2.468 0 1.783-.015 3.219-.015 3.658 0 .355.234.77.893.64 5.162-1.765 8.882-6.76 8.882-12.647 0-7.361-5.82-13.329-13-13.329"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 908 B After Width: | Height: | Size: 908 B |
21
frontend/src/Components/Intro/Container.js
Normal file
@ -0,0 +1,21 @@
|
||||
import styled from 'styled-components';
|
||||
|
||||
import logoMartin from './logo_martin.svg';
|
||||
|
||||
export default styled.div`
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
|
||||
height: 100vh;
|
||||
padding: 7vw;
|
||||
|
||||
color: #fff;
|
||||
|
||||
background: url(${logoMartin}) no-repeat;
|
||||
background-size: contain;
|
||||
|
||||
@media (max-width: 500px) {
|
||||
justify-content: center;
|
||||
}
|
||||
`;
|
13
frontend/src/Components/Intro/Description.js
Normal file
@ -0,0 +1,13 @@
|
||||
import styled from 'styled-components';
|
||||
|
||||
export default styled.div`
|
||||
max-width: 500px;
|
||||
margin-bottom: 70px;
|
||||
|
||||
font-size: 30px;
|
||||
line-height: 1.45;
|
||||
|
||||
@media (max-width: 500px) {
|
||||
font-size: 20px;
|
||||
}
|
||||
`;
|
@ -1,57 +0,0 @@
|
||||
.intro {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
background: url("logo_martin.svg") no-repeat;
|
||||
background-size: contain;
|
||||
}
|
||||
|
||||
.introblock {
|
||||
flex-direction: column;
|
||||
align-self: center;
|
||||
padding-left: 50%;
|
||||
}
|
||||
|
||||
.martin {
|
||||
margin-top: 150px;
|
||||
font-family: VremenaGroteskBold, sans-serif;
|
||||
font-size: 80px;
|
||||
font-weight: bold;
|
||||
letter-spacing: 15px;
|
||||
color: rgba(0,0,0,0);
|
||||
-webkit-text-stroke-width: 2px;
|
||||
-webkit-text-stroke-color: white;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.slogan {
|
||||
margin-top: 45px;
|
||||
margin-bottom: 80px;
|
||||
font-size: 35px;
|
||||
line-height: 50px;
|
||||
font-weight: normal;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.gitbutton{
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items:center;
|
||||
width: 200px;
|
||||
height: 50px;
|
||||
padding: 10px 10px;
|
||||
font-size: 20px;
|
||||
font-weight: normal;
|
||||
background-color: rgba(0,0,0,0);
|
||||
border: solid 1px #ffffff;
|
||||
color: #ffffff;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.gitbutton:hover{
|
||||
background-color: #0E0E1E;
|
||||
box-shadow: 3px 3px 0px rgba(115, 0, 255, 1);
|
||||
border-color: #0E0E1E;
|
||||
}
|
||||
|
||||
|
@ -1,23 +0,0 @@
|
||||
import React from 'react';
|
||||
import './Intro.css';
|
||||
|
||||
import octocat from './kotik.svg';
|
||||
|
||||
const Intro = () => (
|
||||
<div className='intro'>
|
||||
<div className='introblock'>
|
||||
<div className='martin'>Martin</div>
|
||||
<div className='slogan'>
|
||||
Vector Tiles from Large Databases
|
||||
<br />
|
||||
on the Fly
|
||||
</div>
|
||||
<a href='https://github.com/urbica/martin' className='gitbutton'>
|
||||
View on Github
|
||||
<img src={octocat} alt='octocat' />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
export default Intro;
|
22
frontend/src/Components/Intro/Intro.jsx
Normal file
@ -0,0 +1,22 @@
|
||||
import React from 'react';
|
||||
|
||||
import Container from './Container';
|
||||
import Title from './Title';
|
||||
import Description from './Description';
|
||||
import GitHubButton from '../GitHubButton';
|
||||
|
||||
const Intro = () => (
|
||||
<Container>
|
||||
<div>
|
||||
<Title>
|
||||
Martin
|
||||
</Title>
|
||||
<Description>
|
||||
Vector Tiles from Large Databases on the Fly
|
||||
</Description>
|
||||
<GitHubButton />
|
||||
</div>
|
||||
</Container>
|
||||
);
|
||||
|
||||
export default Intro;
|
17
frontend/src/Components/Intro/Title.js
Normal file
@ -0,0 +1,17 @@
|
||||
import styled from 'styled-components';
|
||||
|
||||
export default styled.h1`
|
||||
margin: 0 0 20px;
|
||||
|
||||
font-size: 80px;
|
||||
letter-spacing: 15px;
|
||||
color: transparent;
|
||||
-webkit-text-stroke-width: 2px;
|
||||
-webkit-text-stroke-color: white;
|
||||
text-transform: uppercase;
|
||||
|
||||
@media (max-width: 500px) {
|
||||
font-size: 50px;
|
||||
-webkit-text-stroke-width: 1px;
|
||||
}
|
||||
`;
|
@ -1,3 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 34 34">
|
||||
<path fill="#ffffff" fill-rule="evenodd" d="M13.546 0c-7.18 0-13 5.968-13 13.33 0 5.888 3.724 10.885 8.89 12.647.65.123.888-.29.888-.641 0-.318-.012-1.368-.018-2.482-3.616.807-4.38-1.572-4.38-1.572-.59-1.541-1.443-1.95-1.443-1.95-1.18-.828.089-.811.089-.811 1.305.094 1.993 1.374 1.993 1.374 1.16 2.037 3.041 1.448 3.783 1.108.117-.862.453-1.45.825-1.783-2.887-.337-5.923-1.48-5.923-6.587 0-1.455.508-2.644 1.34-3.578-.135-.335-.58-1.691.126-3.527 0 0 1.091-.358 3.576 1.366a12.172 12.172 0 0 1 3.254-.448c1.104.005 2.217.153 3.256.448 2.482-1.724 3.572-1.366 3.572-1.366.707 1.836.262 3.192.127 3.527.834.934 1.338 2.123 1.338 3.578 0 5.12-3.041 6.247-5.936 6.577.466.413.882 1.224.882 2.468 0 1.783-.015 3.219-.015 3.658 0 .355.234.77.893.64 5.162-1.765 8.882-6.76 8.882-12.647 0-7.361-5.82-13.329-13-13.329"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 908 B |
@ -2,4 +2,6 @@ import styled from 'styled-components';
|
||||
|
||||
export default styled.div`
|
||||
position: relative;
|
||||
|
||||
margin-bottom: 50px;
|
||||
`;
|
||||
|
@ -4,7 +4,7 @@ export default styled.div`
|
||||
position: absolute;
|
||||
top: 0;
|
||||
|
||||
width: 350px;
|
||||
width: 320px;
|
||||
padding: 25px;
|
||||
border-bottom-right-radius: 5px;
|
||||
box-shadow: 0 2px 3px 0 rgba(0, 0, 0, 0.5);
|
||||
@ -12,4 +12,10 @@ export default styled.div`
|
||||
color: #dadfee;
|
||||
|
||||
z-index: 2;
|
||||
|
||||
@media (max-width: 500px) {
|
||||
position: initial;
|
||||
|
||||
width: 100%;
|
||||
}
|
||||
`;
|
||||
|
@ -3,14 +3,11 @@ import DayPicker, { DateUtils } from 'react-day-picker';
|
||||
import { debounce } from 'debounce';
|
||||
import 'react-day-picker/lib/style.css';
|
||||
|
||||
import layers from '../../../config/layers';
|
||||
import { JAN, DEC } from '../../../config/constants';
|
||||
import dateConverter from '../../../utils/dateConverter';
|
||||
|
||||
import Container from './Container';
|
||||
import Layer from './Layer';
|
||||
import Title from './Title';
|
||||
import Description from './Description';
|
||||
import Layers from './Layers';
|
||||
import Separator from './Separator';
|
||||
import Range from './Range';
|
||||
import DayPickerContainer from './DayPicker';
|
||||
@ -44,12 +41,10 @@ class Filters extends PureComponent {
|
||||
);
|
||||
};
|
||||
|
||||
toggleLayerHandler = layerId => () => {
|
||||
this.props.toggleLayer(layerId);
|
||||
};
|
||||
|
||||
render() {
|
||||
const { visibleLayer, range: { from, to }, hour } = this.props;
|
||||
const {
|
||||
visibleLayer, toggleLayer, range: { from, to }, hour
|
||||
} = this.props;
|
||||
const modifiers = {
|
||||
start: from,
|
||||
end: to
|
||||
@ -60,26 +55,10 @@ class Filters extends PureComponent {
|
||||
|
||||
return (
|
||||
<Container>
|
||||
{layers.map((layer) => {
|
||||
const isLayerVisible = visibleLayer === layer.id;
|
||||
|
||||
return (
|
||||
<Layer
|
||||
key={layer.id}
|
||||
onClick={this.toggleLayerHandler(layer.id)}
|
||||
isLayerVisible={isLayerVisible}
|
||||
>
|
||||
<Title>
|
||||
{layer.title}
|
||||
</Title>
|
||||
{isLayerVisible && (
|
||||
<Description>
|
||||
{layer.description}
|
||||
</Description>
|
||||
)}
|
||||
</Layer>
|
||||
);
|
||||
})}
|
||||
<Layers
|
||||
visibleLayer={visibleLayer}
|
||||
toggleLayer={toggleLayer}
|
||||
/>
|
||||
<Separator />
|
||||
<Range onClick={this.toggleDayPicker}>
|
||||
{`${dateFrom} – ${dateTo}`}
|
||||
@ -88,10 +67,7 @@ class Filters extends PureComponent {
|
||||
<DayPickerContainer>
|
||||
<DayPicker
|
||||
numberOfMonths={1}
|
||||
selectedDays={[from, {
|
||||
from,
|
||||
to
|
||||
}]}
|
||||
selectedDays={[from, { from, to }]}
|
||||
modifiers={modifiers}
|
||||
onDayClick={this.handleDayClick}
|
||||
captionElement={CaptionElement}
|
||||
|
41
frontend/src/Components/Map/Filters/Layers/Layers.js
Normal file
@ -0,0 +1,41 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import layers from '../../../../config/layers';
|
||||
|
||||
import Layer from './Layer';
|
||||
import Title from './Title';
|
||||
import Description from './Description';
|
||||
|
||||
class Layers extends PureComponent {
|
||||
toggleLayerHandler = layerId => () => {
|
||||
this.props.toggleLayer(layerId);
|
||||
};
|
||||
|
||||
render() {
|
||||
const { visibleLayer } = this.props;
|
||||
|
||||
return (
|
||||
layers.map((layer) => {
|
||||
const isLayerVisible = visibleLayer === layer.id;
|
||||
|
||||
return (
|
||||
<Layer
|
||||
key={layer.id}
|
||||
onClick={this.toggleLayerHandler(layer.id)}
|
||||
isLayerVisible={isLayerVisible}
|
||||
>
|
||||
<Title>
|
||||
{layer.title}
|
||||
</Title>
|
||||
{isLayerVisible && (
|
||||
<Description>
|
||||
{layer.description}
|
||||
</Description>
|
||||
)}
|
||||
</Layer>
|
||||
);
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Layers;
|
1
frontend/src/Components/Map/Filters/Layers/index.js
Normal file
@ -0,0 +1 @@
|
||||
export { default } from './Layers';
|
@ -9,10 +9,7 @@ import dateConverter from '../../utils/dateConverter';
|
||||
import Container from './Container';
|
||||
import Filters from './Filters';
|
||||
|
||||
const mapStyle = {
|
||||
height: '70vh',
|
||||
marginBottom: '95px'
|
||||
};
|
||||
const mapStyle = { height: '70vh' };
|
||||
|
||||
class Map extends PureComponent {
|
||||
state = {
|
||||
@ -28,7 +25,11 @@ class Map extends PureComponent {
|
||||
mapboxgl.accessToken = MAPBOX_TOKEN;
|
||||
this.map = new mapboxgl.Map({
|
||||
container: 'map',
|
||||
style: MAPBOX_STYLE
|
||||
style: MAPBOX_STYLE,
|
||||
center: [-74.005308, 40.713370],
|
||||
pitch: 45,
|
||||
minZoom: 8,
|
||||
maxZoom: 16
|
||||
});
|
||||
this.nav = new mapboxgl.NavigationControl();
|
||||
|
||||
@ -90,10 +91,6 @@ class Map extends PureComponent {
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<div
|
||||
id='map'
|
||||
style={mapStyle}
|
||||
/>
|
||||
<Filters
|
||||
visibleLayer={visibleLayer}
|
||||
range={range}
|
||||
@ -101,6 +98,10 @@ class Map extends PureComponent {
|
||||
toggleLayer={this.toggleLayer}
|
||||
changeFilter={this.changeFilter}
|
||||
/>
|
||||
<div
|
||||
id='map'
|
||||
style={mapStyle}
|
||||
/>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
10
frontend/src/Components/TryIt.js
Normal file
@ -0,0 +1,10 @@
|
||||
import styled from 'styled-components';
|
||||
|
||||
export default styled.div`
|
||||
max-width: 1024px;
|
||||
padding: 7vw;
|
||||
margin: auto;
|
||||
|
||||
font-size: 30px;
|
||||
line-height: 40px;
|
||||
`;
|
17
frontend/src/config/features.js
Normal file
@ -0,0 +1,17 @@
|
||||
export default [
|
||||
{
|
||||
id: 1,
|
||||
title: 'Turning Data into Vector Tiles',
|
||||
description: 'Martin creates Mapbox Vector Tiles from any PostGIS table or view'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: 'Generating Tiles with Functions',
|
||||
description: 'Martin is the only vector tile server capable of creating tiles using database functions directly'
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: 'Filtering and Aggregating Data on the Fly',
|
||||
description: 'Martin is ideal for large datasets as it allows passing parameters from a URL into a user function to filter features and aggregate attribute values'
|
||||
}
|
||||
];
|