Related
I have been trying to implement wfs-t service in openlayers3 in system. I can able to see the
<wfs:FeatureCollection xmlns="http://www.opengis.net/wfs" xmlns:wfs="http://www.opengis.net/wfs" xmlns:sf="http://www.openplans.org/spearfish" xmlns:gml="http://www.opengis.net/gml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/WFS-basic.xsd http://www.openplans.org/spearfish http://localhost:9999/geoserver/sf/wfs?service=WFS&version=1.0.0&request=DescribeFeatureType&typeName=sf%3AAPRoad50MMI2015">
<gml:boundedBy>
<gml:Box srsName="EPSG:4326">
<gml:coordinates xmlns:gml="http://www.opengis.net/gml" decimal="." cs="," ts=" ">76.771293,12.625601 84.727878,19.166098</gml:coordinates>
</gml:Box>
My XML for the delete from my geoserver with featureID are:
<Transaction xmlns="http://www.opengis.net/wfs" service="WFS" version="1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd"><Delete typeName="feature:jktouristspots50poi2015" xmlns:feature="http://172.31.4.67:9999/geoserver/mywork"><Filter xmlns="http://www.opengis.net/ogc"><FeatureId fid="jktouristspots50poi2015.55"/></Filter></Delete></Transaction>
1. My geoserver deatails:
Build Information
GeoServer Version
2.11.1
Git Revision
0628848420a522efc1c6bbd90cb3346038929f6a
Build Date
18-May-2017 22:36
GeoTools Version
17.1 (rev 86d8efab5104df08c81acf7b2f2342e08c9dea4b)
GeoWebCache Version
1.11.0 (rev 1.11.x/02b79570ae64d548f9fb39bcab5edc9cb4d0c992)
For the above WFS request i have set my ajax function like below:
<script type="text/javascript">
var formatWFS = new ol.format.WFS();
var formatGML = new ol.format.GML({
featureNS: 'http://localhost:9999/geoserver/mywork',
featureType: 'jktouristspots50poi2015',
srsName: 'EPSG:4326'
});
alert("GML",formatGML);
var xs = new XMLSerializer();
var sourceWFS = new ol.source.Vector({
loader: function (extent, resolution, projection) {
var url = 'http://localhost:9999/geoserver/mywork/wfs?service=WFS&' +
'version=1.1.0&request=GetFeature&typename=mywork:jktouristspots50poi2015&' +
'outputFormat=text/javascript&srsname=EPSG:4326&' +
'bbox=' + extent.join(',') + ',EPSG:4326';
alert(url);
$.ajax({
url: url,
dataType: 'jsonp',
jsonpCallback: 'callback:loadFeatures',
jsonp: 'format_options'
}).done(function (response) {
alert("i am done");
});
},
strategy: ol.loadingstrategy.bbox
});
window.loadFeatures = function (response) {
layerWFS
.getSource()
.addFeatures(new ol.format.GeoJSON().readFeatures(response));
};
var layerWFS = new ol.layer.Vector({
source: sourceWFS
});
var interaction;
var interactionSelectPointerMove = new ol.interaction.Select({
condition: ol.events.condition.pointerMove
});
var interactionSelect = new ol.interaction.Select({
style: new ol.style.Style({
stroke: new ol.style.Stroke({
color: '#FF2828'
})
})
});
var interactionSnap = new ol.interaction.Snap({
source: layerWFS.getSource()
});
var map = new ol.Map({
target: 'map',
controls: [],
interactions: [
interactionSelectPointerMove,
new ol.interaction.MouseWheelZoom(),
new ol.interaction.DragPan()
],
layers: [
new ol.layer.Tile({
title: 'India',
source: new ol.source.TileWMS({
url: 'http://ndem.nrsc.gov.in/geoserver_v3/ndem50k/wms',
params: {LAYERS: 'ndem50k:stateadmin50census2011'}
})
}),
layerWFS
],
view: new ol.View({
projection: 'EPSG:4326',
center: [82.491,21.899],
zoom: 5
})
});
//wfs-t
var dirty = {};
var transactWFS = function (mode, f) {
var node;
switch (mode) {
case 'insert':
node = formatWFS.writeTransaction([f], null, null, formatGML);
alert("after insert node",node);
break;
case 'update':
node = formatWFS.writeTransaction(null, [f], null, formatGML);
break;
case 'delete':
node = formatWFS.writeTransaction(null, null, [f], formatGML);
break;
}
var payload = xs.serializeToString(node);
<!-- '<Transaction xmlns="http://www.opengis.net/wfs" service="WFS" version="1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd"><Delete typeName="feature:jktouristspots50poi2015" xmlns:feature="http://172.31.4.67:9999/geoserver/mywork"><Filter xmlns="http://www.opengis.net/ogc"><FeatureId fid="jktouristspots50poi2015.55"/></Filter></Delete></Transaction>'; -->
alert(payload);
$.ajax('http://localhost:9999/geoserver/mywork/ows', {
service: 'WFS',
type: 'POST',
dataType: 'xml',
processData: true,
contentType: 'text/xml',
data: {data:payload}
}).done(function() {
alert("gekki hi ");
console.log("indside done");
sourceWFS.clear();
});
alert("out i am"+payload);
};
$('button').click(function () {
alert();
$(this).siblings().removeClass('btn-active');
$(this).addClass('btn-active');
map.removeInteraction(interaction);
interactionSelect.getFeatures().clear();
map.removeInteraction(interactionSelect);
switch ($(this).attr('id')) {
case 'btnEdit':
map.addInteraction(interactionSelect);
interaction = new ol.interaction.Modify({
features: interactionSelect.getFeatures()
});
alert("am edit "+interaction);
map.addInteraction(interaction);
map.addInteraction(interactionSnap);
dirty = {};
interactionSelect.getFeatures().on('add', function (e) {
e.element.on('change', function (e) {
//alert("i am add ");
dirty[e.target.getId()] = true;
});
});
interactionSelect.getFeatures().on('remove', function (e) {
var f = e.element;
if (dirty[f.getId()]) {
alert("i am in remove");
delete dirty[f.getId()];
var featureProperties = f.getProperties();
delete featureProperties.boundedBy;
var clone = new ol.Feature(featureProperties);
clone.setId(f.getId());
transactWFS('update', clone);
}
});
break;
case 'btnPoint':
interaction = new ol.interaction.Draw({
type: 'Point',
source: layerWFS.getSource()
});
map.addInteraction(interaction);
interaction.on('drawend', function (e) {
transactWFS('insert', e.feature);
});
break;
case 'btnLine':
alert("line feature draw");
interaction = new ol.interaction.Draw({
type: 'LineString',
source: layerWFS.getSource()
});
map.addInteraction(interaction);
interaction.on('drawend', function (e) {
var myAttrValue = prompt("Enter Attribute", "");
var myFeature= e.feature;
if (myAttrValue != null) {
myFeature.set('column', myAttrValue);
}
transactWFS('insert', myFeature);
});
break;
case 'btnArea':
interaction = new ol.interaction.Draw({
type: 'Polygon',
source: layerWFS.getSource()
});
interaction.on('drawend', function (e) {
transactWFS('insert', e.feature);
});
map.addInteraction(interaction);
break;
case 'btnDelete':
interaction = new ol.interaction.Select();
interaction.getFeatures().on('add', function (e) {
transactWFS('delete', e.target.item(0));
interactionSelectPointerMove.getFeatures().clear();
interaction.getFeatures().clear();
});
map.addInteraction(interaction);
break;
default:
break;
}
});
</script>
How can i enable global setting in geoserver, what is ows? If i pass the existing path also its throwing error like:
PATH OF MY WORKSPACE IN GEOSERVER:
C:\Program Files (x86)\GeoServer 2.11.1\data_dir\workspaces\mywork\jktourisam
wfs-t.jpg
postgislayer.html:1 XMLHttpRequest cannot load http://localhost:9999/geoserver/mywork/wfs.
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'http://localhost' is therefore not allowed access. The response had HTTP status code 403.
I have tried many ways, i couldn't find the solution.......
I was able to view the added WFS vector layer on my map. Is there any parameter wrong in my code? Mean while i have tested WFS-T with same url of layer from my geoserver, at there also i cant delete and insert features to geoserver and postgres, but i can able to draw on map by using that polygon,line and point features on map and can able to retrieve the feature id? I want to implement CQL and ECQL filters also in my code kindly provide any reference links to learn. Thank you
Mean while alerting success from ajax call(POST) is also not working, i think it was because of the wrong url i am pass? Is it correct? Please guide me to set environment in geoserver to perform wfs-t..
You need to enable CORS in your container. See this question if you are using Jetty as your container, or this question if you use tomcat.
What I am trying to achieve:
Generate Map
Get Bounds information for Map
Make Ajax call passing Bounds information, data returned is Marker info
Populate Map with Markers
I am stuck because I cannot get the Ajax call to trigger.
The code seems to stop running after the alert("ajax ready"). I have a breakpoint on my controller action which never gets hit.
The only error I am getting is that "nE is undefined", however if I put in an alert the line after I am setting the value, then the the value is shown, so am not even sure that is relevant.
I have worked successfully with an earlier version of Google Maps, V3 seems a bit different. I couldn't get the lines of code to set the bounds to run until they were placed in an event listener. I tried the same with the Ajax call but doesn't make a difference.
I do know that I am not adding the markers to the map within the ajax call, I have yet to get to that part.
Javascript:
function initMap() {
var markers = [];
var map = new google.maps.Map(document.getElementById('local-map'), {
center: { lat: 51.509865, lng: -0.118092 },
zoom: 15
});
var bounds = undefined;
var nE = undefined;
var sW = undefined;
google.maps.event.addListener(map, 'bounds_changed', function () {
bounds = map.getBounds();
nE = bounds.getNorthEast();
sW = bounds.getSouthWest();
});
alert("ajax ready");
$.ajax({
type: "POST",
url: '/Home/GetMapMarkers',
data: { neLatitude: nE.lat(), neLongitude: ne.lng(), swLatitude: sW.lat(), swLongitude: sW.lng() }
}).done(function (data) {
for (i = 0; i < data.length; i++)
{
var marker = new google.maps.Marker({
position: new google.maps.LatLng(data[i].Latitude, data[i].Longitude),
map: map,
title: data[i].RestaurantName
});
markers.push(marker);
}
});
}
The "bounds_changed" listener will fire asynchronously when the map bounds changes. You need to put your AJAX call inside its callback function (when/where the new bounds is available):
google.maps.event.addListener(map, 'bounds_changed', function () {
bounds = map.getBounds();
nE = bounds.getNorthEast();
sW = bounds.getSouthWest();
alert("ajax ready");
$.ajax({
type: "POST",
url: '/Home/GetMapMarkers',
data: { neLatitude: nE.lat(), neLongitude: ne.lng(), swLatitude: sW.lat(), swLongitude: sW.lng() }
}).done(function (data) {
for (i = 0; i < data.length; i++)
{
var marker = new google.maps.Marker({
position: new google.maps.LatLng(data[i].Latitude, data[i].Longitude),
map: map,
title: data[i].RestaurantName
});
markers.push(marker);
}
});
});
I have a problem when I call a REST service by POST to updates tables in MySQL.
I'm working with BackboneJS and when click Save button, call the service and passed POST parameters
$.ajax({
type: 'POST',
url: rootURL,
data: dataJson, //data send to REST service by POST
cacheControl: "no-cache",
dataType: "json",
success: function(data){
console.log("OK");
},
error: function(data){
console.log(data.msg);
}
});
But the problem occurs when income and leave the editing screen. Assuming I made a change and it worked perfectly bringing me back a single "OK", when I go back into the editing screen and record again, I get twice the word "OK".
If I repeat this step to enter and exit the screen edition, duplicate responses are based on the number of times into the screen edition.
I don't know if it's a problem about I'm doing wrong with BackboneJS...?? I'm doing this:
editAdverts: function(){
var editAdvertsView = new EditAdvertsView ();
$('#container-page').append(editAdvertsView.render(idAdverts).el);
}
It can also be a topic of AJAX?
I hope someone can help me with this issue because I am not an expert in BackboneJS
Thanks a lot!
Diego
It's hard to tell without more code but I'm pretty sure it's because you are creating a model each time you are using editAdvert.
Instead of creating a model each time just create one at the init of your view then call the fetch/save function anytime you need an update. Creating the model once is enough.
edit: zombies views is a good thing to check too as brent noticed in comment, we can't tell without more code.
This is de code about route:
var Index = {
start: function() {
var list_view = new MainView();
}
};
var AppRouter = Backbone.Router.extend ({
routes: {
'goAdvert' : 'goAdvert'
},
goAdvert: function(){
var viewAdvertsView = new ViewAdvertsView();
$('#container-page').append(viewAdvertsView.render().el);
}
});
var MainView= Backbone.View.extend({
el: $('#contenedor-body'),
initialize: function() {
this.render();
},
render: function() {
// here is the code about main page. It's not important!
},
});
new AppRouter;
Index.start();
Backbone.history.start();
This is the viewAdvertsView.js
define([
'jquery',
'underscore',
'backbone',
'jqueryuniform',
'bootstrap',
'handlebars',
'jqueryDataTables',
'dtBootstrap',
'../../view/editAdvertsView',
], function($, _, Backbone, jqueryuniform, Bootstrap, Handlebars, JQueryDataTables, DtBootstrap, EditAdvertsView){
var viewAdverts = Backbone.View.extend({
events: {
'click #edit' : 'editAdvert'
}
editAdvert: function(){
$('#container-page').empty();
var idAdvert = $(event.target).data('id');
editAdvertView = new EditAdvertsView();
$('#container-page').append(editAdvertView.render(idAdvert).el);
},
render: function() {
// load viewAdverts
}
});
return viewAdverts;
}
);
And this is editAdvertsView.js
define([
'jquery',
'underscore',
'backbone',
'jqueryuniform',
'bootstrap',
'handlebars',
'jqueryDataTables',
'functions',
'sessionManage',
'slimscroll',
'jqueryCustomSlimscroll',
'slimscrollMin',
'jqueryblockui',
'text!../../html/editAdverts.html',
'maps',
'fancybox'
], function($, _, Backbone, jqueryuniform, Bootstrap, Handlebars, JQueryDataTables,
Functions, SessionManage, Slimscroll, JqueryCustomSlimscroll, SlimscrollMin,
Jqueryblockui, EditAdverts, Maps, Fancybox){
var Advert= Backbone.View.extend({
el: $('#container-page'),
events: {
'click #saveChanges' : 'doSaveChanges'
},
doSaveChanges: function(){
var data = null;
var rootURL = "http://localhost/php/slim/slim/advert/update" + "?date=" + $.now();
dataJson = {
id: $("#id").val(),
product: $("#product").val(),
price: $("#price").val(),
client: $("#client").val(),
country: $("#country").val(),
tel: $("#telephone").val(),
cel: $("#cellphone").val()
};
$.ajax({
type: 'POST',
url: rootURL,
data: dataJson,
cacheControl: "no-cache",
dataType: "json",
success: function(data){
console.log("OK");
error: function(data){
console.log(data.msg);
}
}
},
render: function(codInmueble) {
var self = this;
var editTemplate = Handlebars.compile(EditAdverts);
self.$el.html(editTemplate());
return this;
}
});
return Advert;
}
);
I have written some code to fetch zipcodes from a mysql db via ajax call, geocode them, then make markers out of them on a GMap. The markers are clickable to reveal some demographic data. It works if i leave the alert in the each loop uncommented. If not it only shows about 8 markers. Any and all help is appreciated. Relevant code:
function initialize() {
var geocoder = new google.maps.Geocoder();
var markers = [];
var latlng = new google.maps.LatLng("33.7463915", "-117.86044720000001");
var myOptions = {
zoom: 11,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
$.ajax({
url: 'getzips.php',
dataType: 'json',
success: function (data) {
$.each(data.rows, function(i, item) {
//alert(item.zip);
if (geocoder) {
geocoder.geocode({ 'address': item.zip }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var latlng = new google.maps.LatLng(results[0].geometry.location.lat(), results[0].geometry.location.lng());
var marker = new google.maps.Marker({
position: latlng,
map: map,
title: item.zip
});
var infowindow = new google.maps.InfoWindow({
content: item.zip
});
google.maps.event.addListener(marker, "click", function() {
$.ajax({
url: 'getinfo.php?zipcode=' + marker.title,
success: function(data){
infowindow.setContent(data);
infowindow.open(map, marker);
}
});
});
markers.push(marker);
}
});
}
else
alert("geocode error");
});
}
});
//alert(markers.length);
}
Google Geocoding API has both query and rate limits. You need to slow down when querying.
Use of the Google Geocoding API is subject to a query limit of 2,500 geolocation requests per day.
Additionally, we enforce a request rate limit to prevent abuse of the service.
I have a jqplot bar chart and I want the chart data to be changed when the user changes the value on a drop-down list. That works, but the problem is the bar chart redraws, one over another, each time the user changes the values.
How can I update or reload the bars without drawing the whole thing again? Is there any property value to be set?
Chart data changes according to an ajax call:
$.ajax({
url: '/Home/ChartData',
type: 'GET',
data: { Id: Id },
dataType: 'json',
success: function (data) {
$.jqplot('chartDiv', [a, b], CreateBarChartOptions(xAxis));
}});
function CreateBarChartOptions(xAxis) {
var optionsObj = {
title: 'Stat',
axes: {
xaxis: {
renderer: $.jqplot.CategoryAxisRenderer,
ticks: xAxis
},
yaxis: { min: 0 }
},
series: [{ label: 'A' }, { label: 'B'}],
seriesDefaults: {
shadow: true,
renderer: $.jqplot.BarRenderer,
rendererOptions: {
barPadding: 8,
barMargin: 10
}
},
};
return optionsObj;
}
A reply would be highly appreciated. Thanks.
What you want to do is call jqPlot's .replot() method when you draw the new chart. Change your ajax call to look like this:
$.ajax({
url: '/Home/ChartData',
type: 'GET',
data: { Id: Id },
dataType: 'json',
success: function (data) {
$.jqplot('chartDiv', [a, b], CreateBarChartOptions(xAxis)).replot();
}});
Try having your chart object as a global variable in your script as:
var plot1 = $.jqplot('chartDiv', [a, b], CreateBarChartOptions(xAxis));
Then on success reset the data, axesScale and replot as:
var newData = [['a',1],['b',2],['c',3]];
plot1.series[0].data = newData;
plot1.resetAxesScale();
plot1.replot();
Ref: https://groups.google.com/group/jqplot-users/browse_thread/thread/59df82899617242b?pli=1
Each time before redrawing the graph, just destroy the existing1.
$.ajax({
url: '/Home/ChartData',
type: 'GET',
data: { Id: Id },
dataType: 'json',
success: function (data) {
if(plot)
{
plot.destroy();
}
var plot=$.jqplot('chartDiv', [a, b], CreateBarChartOptions(xAxis));
}});
Took me a while to find an answer for the script generated data, so I'm going to post this right here. I used a combination of the above code.
I created a global var, named plot3 within my script file. Then created the below function. When this is called with a redraw boolean, it determines if I need to destroy and redraw or draw for the first time.
What first bit of code does is gets data from my jqgrid, (which is being updated in a different function), and updates the arrays. The second bit, determines my interval ticks, on the x-axis dependent upon my length of data.
function DrawGraph(bRedraw){
var testTimes = [];
testTimes = $('#polarizationTable').jqGrid('getCol', 'TestTime', testTimes, false);
var RdgA = $('#polarizationTable').jqGrid('getCol', 'RdgA', RdgA, false);
var RdgB = $('#polarizationTable').jqGrid('getCol', 'RdgB', RdgB, false);
var readingLineA = [];
for (var i=0; i<testTimes.length; i++){
readingLineA.push([testTimes[i], RdgA[i]]);
}
var readingLineB = [];
for (var i=0; i<testTimes.length; i++){
readingLineB.push([testTimes[i], RdgB[i]]);
}
var maxX = $("#testLength").val();
var lengthX = testTimes.length;
var tickIntervalX = Math.round(maxX/10);
if(bRedraw == true)
{
plot3.destroy();
bRedraw = false;
}
if(bRedraw == false)
{
plot3 = $.jqplot('chart3', [readingLineA, readingLineB],
{
title:'Graph',
series:[{label:'Reading - A'}, {label:'Reading - B'} ],
legend:{show:true, location:'se'},
// You can specify options for all axes on the plot at once with
// the axesDefaults object. Here, we're using a canvas renderer
// to draw the axis label which allows rotated text.
axes:{
xaxis:{
label:'Minutes',
syncTicks: true,
min: 0,
numberTicks: 10,
tickInterval: tickIntervalX,
max: maxX*1.1,
labelRenderer: $.jqplot.CanvasAxisLabelRenderer,
labelOptions: {
fontSize: '12pt'
},
},
yaxis:{
label:'Data',
min: 0,
numberTicks: 10,
labelRenderer: $.jqplot.CanvasAxisLabelRenderer,
labelOptions: {
fontSize: '12pt'
}
},
}
});
}
}
Here is a full example of how to dynamically update the plot with new data without reloading the page:
<div id="chart1" style="height: 300px; width: 500px; position: relative;"></div>
<button>New data point</button>
<script type="text/javascript">
var storedData = [3, 7];
var plot1;
renderGraph();
$('button').click( function() {
doUpdate();
});
function renderGraph() {
if (plot1) {
plot1.destroy();
}
plot1 = $.jqplot('chart1', [storedData]);
}
function doUpdate() {
var newVal = Math.random();
storedData.push(newVal);
renderGraph();
}
</script>
It's a simplified version of this guy's post: JQPlot auto refresh chart with dynamic ajax data
$('#chart).html('');
chart is the DIV where chart is created.
this does the trick, nothing fancy by effective.
Maybe this will help. I on the other hand is having problem with getting replot to work at all, but i'am using a dataRenderer.
$.ajax({
url: '/Home/ChartData',
type: 'GET',
data: { Id: Id },
dataType: 'json',
success: function (data) {
$('chartDiv').empty();
$.jqplot('chartDiv', [a, b], CreateBarChartOptions(xAxis));
}});
hope this helps
jQuery(document).ready(function(){
jQuery.ajax({
url: '/review_graphs/show',
type: 'GET',
success: function (data) {
var plot1 = jQuery.jqplot('chartDiv', [data,data],
{
title: 'Bianual Reviews percentage',
series:[
{
renderer:jQuery.jqplot.BarRenderer,
label:'Average',
stackSeries: true,
dragable: {color: '#ff3366',constrainTo: 'x'},
trendline:{show: false}
},
{
label:'Trend Line',trendline:{show: false}}
],
legend: {
show: true,
placement: 'outsideGrid'
},
axesDefaults: {
tickRenderer: jQuery.jqplot.CanvasAxisTickRenderer ,
tickOptions: {
angle: -30,
fontSize: '10pt'
}
},
axes: {
xaxis: {
renderer: jQuery.jqplot.CategoryAxisRenderer
}
}
});
}});
});
The best method I got is, the div in which you're drawing, clear that before you draw your new graph.
$('#graph_area).children().remove();