Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
findli committed Aug 9, 2018
0 parents commit 58e3232
Show file tree
Hide file tree
Showing 18 changed files with 454 additions and 0 deletions.
8 changes: 8 additions & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"presets": [
"env",
"react",
"es2015",
"stage-0"
]
}
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
* ошибочность определения воды 0%
* в демонстрационных целях запрашиваются по 20 слуайных точек через graphql пока не наберется 100 точек не над водой.
* запуск: <br/>
npm i<br/>
npm run dev<br/>
<a target="_blank" href="http://localhost:4000">http://localhost:4000</a>

<br/>
<img src="./map_example.png" alt="map example">
10 changes: 10 additions & 0 deletions client/components/App.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import React from 'react';
import MapContainer from "./map/MapContainer";

const App = () => {
return (
<MapContainer/>
);
};

export default App;
20 changes: 20 additions & 0 deletions client/components/map/MapContainer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import * as React from 'react';
// import Loadable from 'react-loadable';
import MapStatic from "./MapStatic";

/*
const LoadableMap = Loadable({
loader: () => import(/!* webpackChunkName: "Map" *!/ "./Map"),
loading: () => (<div>Loading ...</div>)
});
*/

class MapContainer extends React.Component<any, any> {

render() {
// return <LoadableMap/>
return <MapStatic/>
};
}

export default MapContainer;
108 changes: 108 additions & 0 deletions client/components/map/MapStatic.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import * as React from 'react';
import * as _ from 'underscore';
import * as $ from 'jquery';
import {graphql} from 'react-apollo';
// @ts-ignore
import query from '../../queries/RandomCoords';

class MapStatic extends React.Component<any, any> {
private map: HTMLImageElement = new Image();
private map_context: any;
private drawn: {}[] = [];
private $people_layer: any;
private max_map_people: Number = 100;
private water_context: any;
private inited: Boolean = false;
private water = new Image();

private static color_is_water(bytes: any) {
let water_color_bytes = [0, 255, 0], our_color_bytes = [bytes[0], bytes[1], bytes[2]];
return _.isEqual(water_color_bytes, our_color_bytes);
}

componentWillReceiveProps(nextProps: Readonly<any>, nextContext: any): void {
if (!nextProps.data || !nextProps.data.randomCoords) return;
if (!this.inited) return;
for (let i = 0; i < 20; i++) {
if (this.drawn.length === 100) break;
let x = nextProps.data.randomCoords[i].lat;
let y = nextProps.data.randomCoords[i].lng;
if (-1 !== this.drawn.indexOf({x: x, y: y})) continue;
// @ts-ignore
let pixels = this.water_context.getImageData(x, y, 1, 1).data;
if (MapStatic.color_is_water(pixels)) continue;
this.$people_layer.append('<div class="person" style="top:' + y + 'px;left:' + x + 'px"></div>');

this.drawn.push({x: x, y: y});
}
if (this.drawn.length < this.max_map_people) {
this.props.data.refetch();
}

}

public componentDidMount() {
let latlon = "40.7300694,-74.0024224";

let interval: any;
this.$people_layer = $('.people');
let drawRandom = () => {
if (!this.props.data || !this.props.data.randomCoords) return;
this.inited = true;
clearInterval(interval);

// this.$people_layer.empty();
let triesLocal = 0;
for (let i = 0; i < 20; i++) {
let x = this.props.data.randomCoords[i].lat;
let y = this.props.data.randomCoords[i].lng;
triesLocal++;
// @ts-ignore
let pixels = this.water_context.getImageData(x, y, 1, 1).data;
if (MapStatic.color_is_water(pixels)) continue;
this.$people_layer.append('<div class="person" style="top:' + y + 'px;left:' + x + 'px"></div>');

if (-1 === this.drawn.indexOf({x: x, y: y})) {
this.drawn.push({x: x, y: y});
}
}
if (this.drawn.length < this.max_map_people) this.props.data.refetch();
};


let waterOnload = () => {
this.water_context.drawImage(this.water, 0, 0, 1024, 256);
interval = setInterval(drawRandom, 250)
};

this.water_context = document.createElement('canvas');
this.water_context.setAttribute('width', '1024');
this.water_context.setAttribute('height', '160');

this.water_context = this.water_context.getContext('2d');

// @ts-ignore
this.map_context = $('canvas.map')[0].getContext('2d');

this.map.crossOrigin = 'http://maps.googleapis.com/crossdomain.xml';
this.map.src = "http://maps.googleapis.com/maps/api/staticmap?scale=2&center=" + latlon +
"&zoom=3&size=1024x160&sensor=false&visual_refresh=true&key=AIzaSyAwCNiAoF0F2iDZ__GJdf07gtg9seL-IQk";

this.map.onload = () => {
this.map_context.drawImage(this.map, 0, 0, 1024, 256);
this.water.crossOrigin = 'http://maps.googleapis.com/crossdomain.xml';
this.water.src = "http://maps.googleapis.com/maps/api/staticmap?scale=2&center=" + latlon +
"&zoom=3&size=1024x160&sensor=false&visual_refresh=true&style=element:labels|visibility:off&style=feature:water|color:0x00FF00&style=feature:transit|visibility:off&style=feature:poi|visibility:off&style=feature:road|visibility:off&style=feature:administrative|visibility:off&key=AIzaSyASP15b_u1uFphv0r7kwlWtxHWXvsB8ouA";
this.water.onload = waterOnload
}
}

render() {
return <div className={'container'}>
<div className="people"></div>
<canvas className="map" width="1024" height="160"/>
</div>
};
}

export default graphql(query)(MapStatic);
36 changes: 36 additions & 0 deletions client/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.98.0/css/materialize.min.css">
<link href="http://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<style>
.container {
position: relative;
width: 1024px;
height: 160px;
overflow: hidden;
}

.people {
position: absolute;
top: 0;
left: 0;
width: 1024px;
height: 160px;
}

.person {
position: absolute;
background: rgba(0, 0, 255, .7);
width: 3px;
height: 3px;
margin-top: 0;
margin-left: 0;

border-radius: 50%;
-moz-border-radius: 50%;
-webkit-border-radius: 50%;
}
</style>
</head>
<body>
<div id="root"/>
</body>
45 changes: 45 additions & 0 deletions client/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import React from 'react';
import ReactDOM from 'react-dom';
import ApolloClient from 'apollo-client';
import {ApolloProvider} from 'react-apollo';
import {HashRouter, Route} from 'react-router-dom';

import App from './components/app';
import {createHttpLink} from 'apollo-link-http';
import {ApolloLink} from 'apollo-link';

import {InMemoryCache} from 'apollo-cache-inmemory';

const httpLink = createHttpLink({
uri: '/graphql', credentials: 'same-origin'
});

const cache = new InMemoryCache({
dataIdFromObject: o => o.id
});

const middlewareLink = new ApolloLink((operation, forward) => {
operation.setContext({
headers: {
// authorization: localStorage.getItem('token') || null,
}
});
return forward(operation)
});
const link = middlewareLink.concat(httpLink);
const client = new ApolloClient({
link,
cache,
});

const Root = () => {
return (
<ApolloProvider client={client}>
<HashRouter>
<Route path="/" component={App}/>
</HashRouter>
</ApolloProvider>
);
};

ReactDOM.render(<Root/>, document.querySelector('#root'));
10 changes: 10 additions & 0 deletions client/queries/RandomCoords.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import gql from 'graphql-tag';

export default gql`
{
randomCoords {
lat,
lng
}
}
`;
5 changes: 5 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const app = require('./server/server');

app.listen(4000, () => {
console.log('Listening');
});
Binary file added map_example.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
62 changes: 62 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
{
"name": "google_maps_and_graphql",
"version": "1.0.0",
"description": "google maps & graphql",
"repository": {
"type": "git",
"url": "github.com/findli"
},
"main": "index.js",
"scripts": {
"dev": "tsc && nodemon index.js --ignore client"
},
"author": "Ian Burtovoy, [email protected]",
"license": "ISC",
"dependencies": {
"nodemon": "1.18.3",
"typescript": "3.0.1",
"apollo-cache-inmemory": "^1.2.1",
"apollo-client": "^2.3.7",
"apollo-link": "^1.2.2",
"apollo-link-http": "^1.5.4",
"axios": "^0.18.0",
"babel-core": "^6.26.3",
"babel-loader": "^7.1.5",
"babel-preset-env": "^1.7.0",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1",
"babel-preset-stage-0": "^6.24.1",
"bcrypt-nodejs": "0.0.3",
"body-parser": "^1.18.3",
"connect-mongo": "^2.0.1",
"express": "^4.16.3",
"express-graphql": "^0.6.12",
"express-session": "^1.15.6",
"graphql": "^14.0.0-rc.2",
"graphql-tag": "^2.9.2",
"html-webpack-plugin": "^3.2.0",
"jquery": "3.3.1",
"load-google-maps-api": "1.3.2",
"lodash": "^4.17.10",
"mongoose": "^5.1.2",
"passport": "^0.4.0",
"passport-local": "^1.0.0",
"react": "16.4.2",
"react-apollo": "^2.1.9",
"react-dom": "^16.4.1",
"react-loadable": "5.4.0",
"react-router": "^4.3.1",
"react-router-dom": "^4.3.1",
"sequelize": "^4.38.0",
"underscore": "1.9.1",
"webpack": "^4.16.2",
"webpack-dev-middleware": "^3.1.3"
},
"devDependencies": {
"@types/underscore": "^1.8.8",
"@types/graphql": "^0.13.4",
"@types/jquery": "3.3.5",
"@types/react": "16.4.8",
"@types/react-loadable": "5.4.1"
}
}
8 changes: 8 additions & 0 deletions server/schema/schema.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const graphql = require('graphql');
const {GraphQLSchema} = graphql;

const RootQueryType = require('./types/root_query_type');

module.exports = new GraphQLSchema({
query: RootQueryType
});
15 changes: 15 additions & 0 deletions server/schema/types/LatLngType.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const graphql = require('graphql');
const {
GraphQLObjectType,
GraphQLFloat,
} = graphql;

const LatLngType = new GraphQLObjectType({
name: 'LatLngType',
fields: {
lat: {type: GraphQLFloat},
lng: {type: GraphQLFloat}
}
});

module.exports = LatLngType;
25 changes: 25 additions & 0 deletions server/schema/types/root_query_type.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
let _ = require("underscore");

const graphql = require('graphql');
const {GraphQLObjectType, GraphQLList} = graphql;
const LatLngType = require('./LatLngType');

const RootQueryType = new GraphQLObjectType({
name: 'RootQueryType',
fields: {
randomCoords: {
type: new GraphQLList(LatLngType),
resolve() {
let coords = [];
for (let i = 0; i < 20; i++) {
let x = _.random(0, 1024);
let y = _.random(0, 160);
coords.push({lat: x, lng: y})
}
return coords;
}
}
}
});

module.exports = RootQueryType;
17 changes: 17 additions & 0 deletions server/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const express = require('express');
const expressGraphQL = require('express-graphql');
const schema = require('./schema/schema');

const app = express();

app.use('/graphql', expressGraphQL({
schema,
graphiql: true
}));

const webpackMiddleware = require('webpack-dev-middleware');
const webpack = require('webpack');
const webpackConfig = require('../webpack.config.js');
app.use(webpackMiddleware(webpack(webpackConfig)));

module.exports = app;
Loading

0 comments on commit 58e3232

Please sign in to comment.