Skip to content

Commit

Permalink
Merge pull request #6 from org-arl/draw-geo-fence
Browse files Browse the repository at this point in the history
Enable user to draw geofence using the map UI.
  • Loading branch information
ngyewch authored Apr 17, 2020
2 parents 0d0b827 + 7a8a2b2 commit faf7931
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 17 deletions.
19 changes: 19 additions & 0 deletions experiments/WebUI/src/assets/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,25 @@

.dropdown_styles:hover .dropdown_content {display: block;}

/******* DrawGeoFence styles *******/
.drawGeoFence_styles{
position: relative;
display: inline-block;
margin-left: 15px;
}

.drawGeoFence_content{
position: absolute;
background-color: #f1f1f1;
/* min-width: 160px; */
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1001;
}

.drawGeoFence_content Button {
margin: 3px;
}

/******* Script Control ********/
.subroutine_select_styles{
width: 150px;
Expand Down
102 changes: 85 additions & 17 deletions experiments/WebUI/src/components/content/MapComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { Row, Container, Dropdown, Button } from 'react-bootstrap';
import { StyleSheet, css } from 'aphrodite';

import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faCrosshairs } from '@fortawesome/free-solid-svg-icons'
import { faCrosshairs, faUndo, faSave, faWindowClose } from '@fortawesome/free-solid-svg-icons'

import { ToastContainer, toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
Expand Down Expand Up @@ -72,9 +72,14 @@ class MapComponent extends React.Component {
polylineArray: [],
pathLimit: 1000,
missionPoints: [],
MissionPointsMarkers: [],
displayGeoFence: true,
displayMissionPts: true,
displayVehiclePath: true
displayVehiclePath: true,
displayVehicle: true,

drawingGeoFence: false,
drawGeoFence: []

};

Expand All @@ -89,6 +94,13 @@ class MapComponent extends React.Component {
this.toggleMissionPts = this.toggleMissionPts.bind(this);
this.toggleVehiclePath = this.toggleVehiclePath.bind(this);

this.enableDrawGeofence = this.enableDrawGeofence.bind(this);
this.undoGeoFencePoint = this.undoGeoFencePoint.bind(this);
this.saveNewGeoFence = this.saveNewGeoFence.bind(this);
this.cancelNewGeoFence = this.cancelNewGeoFence.bind(this);

this.mapOnClick = this.mapOnClick.bind(this);

this.vehicleMarker = readyMarker;

this.vehicleId = null;
Expand Down Expand Up @@ -278,6 +290,7 @@ class MapComponent extends React.Component {
}

viewMission(num){
// TODO: mission not being shown in first function call. Displays only on second call.

this.missionNumber = num;

Expand All @@ -293,14 +306,14 @@ class MapComponent extends React.Component {
this.setState({
missionPoints: this.missions[this.missionNumber]
});
this.MissionPointsMarkers = [];
var MissionPointsMarkers = [];
this.missionPointsArray = [];
for (var i=0; i < this.state.missionPoints.length; i++){

var lat = this.coordSys.locy2lat(this.state.missionPoints[i].mp.y);
var long = this.coordSys.locx2long(this.state.missionPoints[i].mp.x);
this.missionPointsArray.push([lat, long]);
this.MissionPointsMarkers.push(
MissionPointsMarkers.push(
<Marker icon={mapPin} key={i} position={[lat, long]}>
<Popup>
Lat: {lat.toFixed(4)}, Long: {long.toFixed(4)} <br/>
Expand All @@ -309,6 +322,9 @@ class MapComponent extends React.Component {
</Marker>
);
}
this.setState({
MissionPointsMarkers: MissionPointsMarkers
});
}

recentreMap(e){
Expand Down Expand Up @@ -342,14 +358,50 @@ class MapComponent extends React.Component {
}
}

enableDrawGeofence(e){
this.setState({
drawingGeoFence: true
})
}

undoGeoFencePoint() {
var array = [...this.state.drawGeoFence];
if (array.length > 0) {
array.splice(-1, 1);
this.setState({drawGeoFence: array});
}
}

saveNewGeoFence(e){
// TODO: add code to save geofence on vehicle and replace current geofence.

this.setState({
drawingGeoFence: false,
// geoFenceCoordinates: this.state.drawGeoFence,
drawGeoFence: []
});
}

cancelNewGeoFence(e){
this.setState({
drawingGeoFence: false,
drawGeoFence: []
});
}

openNewWindow(tab) {
const href = window.location.href;
const url = href.substring(0, href.lastIndexOf('/') + 1) + tab;
var w = window.open(url, tab, "width=600,height=600,menubar=0,toolbar=0,location=0,personalBar=0,status=0,resizable=1");
}

mapOnClick(e) {
console.log("You clicked the map at " + e.latlng);
console.log(e.latlng);
if (this.state.drawingGeoFence) {
this.setState({
drawGeoFence: [...this.state.drawGeoFence, [e.latlng.lat, e.latlng.lng]]
});
}
}

render() {
Expand All @@ -360,13 +412,28 @@ class MapComponent extends React.Component {
<div key={index}> {index+1} <Button onClick={() => this.viewMission(index)}>View</Button> <Button onClick={() => this.runMission(index)}>Run</Button></div>
);

const geoFence = this.state.displayGeoFence ? <Polygon id="geoFence" positions={this.state.geoFenceCoordinates} color="red"></Polygon> : null;
const geoFence = (this.state.displayGeoFence && !this.state.drawingGeoFence) ? <Polygon id="geoFence" positions={this.state.geoFenceCoordinates} color="red"></Polygon> : null;

const missionPts = (this.state.displayMissionPts && !this.state.drawingGeoFence) ? this.state.MissionPointsMarkers : null;

const missionPath = (this.state.displayMissionPts && !this.state.drawingGeoFence) ? <Polyline id="missionPath" positions={this.missionPointsArray} color="green"></Polyline> : null;

const missionPts = this.state.displayMissionPts ? this.MissionPointsMarkers : null;
const vehiclePath = (this.state.displayVehiclePath && !this.state.drawingGeoFence) ? <Polyline id="vehiclePath" positions={this.state.polylineArray} color="yellow"></Polyline> : null;

const missionPath = this.state.displayMissionPts ? <Polyline id="missionPath" positions={this.missionPointsArray} color="green"></Polyline> : null;
const drawGeoFenceOptions = (this.state.drawingGeoFence) ? <div className="drawGeoFence_content">
<Button type="submit" onClick={this.undoGeoFencePoint}><FontAwesomeIcon icon={faUndo} color="#fff" /></Button>
<Button type="submit" onClick={this.saveNewGeoFence}><FontAwesomeIcon icon={faSave} color="#fff" /></Button>
<Button type="submit" onClick={this.cancelNewGeoFence}><FontAwesomeIcon icon={faWindowClose} color="#fff" /></Button>
</div> : null;

const vehiclePath = this.state.displayVehiclePath ? <Polyline id="vehiclePath" positions={this.state.polylineArray} color="yellow"></Polyline> : null;
const vehicle = this.state.displayVehicle ?
[<Marker icon={this.vehicleMarker} position={position}>
<Popup>
Lat: {this.state.vehiclePosition.latitude.toFixed(4)}, Long: {this.state.vehiclePosition.longitude.toFixed(4)} <br/>
x: {this.state.vehiclePosition.x.toFixed(4)}, y: {this.state.vehiclePosition.y.toFixed(4)}
</Popup>
</Marker>,
<Circle center={position} radius={this.state.positionError}></Circle>] : null;

return (
<div>
Expand All @@ -377,22 +444,18 @@ class MapComponent extends React.Component {
minZoom={1}
maxZoom={17}
/>
<Marker icon={this.vehicleMarker} position={position}>
<Popup>
Lat: {this.state.vehiclePosition.latitude.toFixed(4)}, Long: {this.state.vehiclePosition.longitude.toFixed(4)} <br/>
x: {this.state.vehiclePosition.x.toFixed(4)}, y: {this.state.vehiclePosition.y.toFixed(4)}
</Popup>
</Marker>
<Circle center={position} radius={this.state.positionError}></Circle>

{vehicle}
{geoFence}
{missionPts}
{missionPath}
{vehiclePath}

<Polygon id="drawGeoFence" positions={this.state.drawGeoFence} color="blue"></Polygon>

</LeafletMap>
<div className={css(styles.map_options_styles)}>
<ToolbarComponent onClick={(clickedItem) => {this.openNewWindow(clickedItem)}}/>
<ToolbarComponent onClick={(clickedItem) => {this.openNewWindow(clickedItem)}}/>
<div className="dropdown_styles">
<Button>Missions</Button>
<div className="dropdown_content">
Expand All @@ -403,6 +466,11 @@ class MapComponent extends React.Component {
<Button type="submit" onClick={this.toggleGeoFence}><img title="Toggle Geofence" src={fenceIcon} height={20} width={20}/></Button>
<Button type="submit" onClick={this.toggleMissionPts}><img title="Toggle Mission Points" src={missionPtsIcon} height={25} width={25}/></Button>
<Button type="submit" onClick={this.toggleVehiclePath}><img title="Toggle Vehicle Path" src={pathIcon} height={20} width={20}/></Button>

<div className="drawGeoFence_styles">
<Button type="submit" onClick={this.enableDrawGeofence}>Draw GeoFence</Button>
{drawGeoFenceOptions}
</div>
</div>
</div>
);
Expand Down

0 comments on commit faf7931

Please sign in to comment.