This question already has answers here:
Google maps saving draggable directions
(2 answers)
Closed 4 years ago.
I want to be able to plot a route in Google Maps, modify that route by dragging it, save the changes and reload it at some later time and edit it further. In the same manner as Google's MyMap. Simply saving the origin and destination locations wont work as it wont reload the same route.
I can save all of the points in the via_waypoint[] array. This allows
me to redraw the route as a polyline but it is no longer editable.
The documentation says that the DirectionsResult is returned in JSON
format. So I've tried to convert the DirectionsResult to a JSON
string, save and reload that string as a JSON object and pass it to
the DirectionsRenderer. But it doesn't display and no errors are
thrown.
Below is a sample of what I was trying to do. I've skipped the saving to the database step. I convert the DirectionsResult to a string and then back to a JSON object.
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
var str = JSON.stringify(response))
var obj= JSON.parse(str)
directionsDisplay.setDirections(obj);
}
Any help would be gratefully appreciated.
Thanks
Why not save the coordinates of the waypoint[] array and reintroduce them to the a DirectionsRequest object's waypoints member? Later on, when you reload the page, make a request to the DirectionsService as usual, but with the previously mentioned DirectionsRequest object. It should be draggable if you set draggable to true in the DirectionsRendererOptions of your renderer.
Related
This question already has answers here:
Add a New Item to a Table / List
(2 answers)
Closed 17 days ago.
We have to perform edit functionality where we have to take two scenarios into consideration:
Make changes in existing entries.
Add new entries and update the old entries.
In the 2nd scenario, when we are trying to add a new entry, it is getting added to sap.m.Table but if we make any change in the old entry then the newly added line item is disappearing.
let oContextLineItemEntry = oLineItmTab.getModel().createEntry("/EntityName", {
properties: NewLineItem,
});
let oTmp = oLineItmTab.getBindingInfo("items").template,
oItem = oTmp.clone();
oItem.setBindingContext(oContextLineItemEntry);
oLineItmTab.addItem(oItem);
Here NewLineItem is an object which I want to add and it is blank. It is initiated like below:
NewLineItem = oLineItmTab.getItems()[0].getBindingContext().getObject();
After this, I have removed all the values of the objects attribute.
I tried with OData V2 OneWay binding, but it didn't work.
I saw framework behavior is triggering this interaction
onChange started
onChange completed
I went through these questions on SAP Community:
https://answers.sap.com/questions/699607/newly-added-table-row-disappearing-when-changing-p.html
https://answers.sap.com/questions/13305104/ui5-controls-and-onchange-event-in-a-sapuitabletab.html
After you bind an aggregation it will be managed by the data binding. Therefore you should not try to modify the aggregations. Instead, do the changes in the model and then the aggregation should be updated according to data in the model. e.g.
let newRow = {key: "_your_unique_id_", value: ""};
let model = table.getModel();
let tableData = model.getProperty("/tableEntityName");
tableData.unshift(newRow);
model.setProperty("/tableEntityName", tableData);
Besides that consider to set the growing property of the table to true.
We had raised an OSS note for this issue to which SAP replied, this is not and issue with UI control but the way to use it.
Basically we are not supposed to add new entries when OData binding is being used.
I'm currently working on an application for making geologic maps. I'm using Ruby on Rails for my back end, React for my front end, and Postgres for the database. I am using React Leaflet to display the maps (abstracts Leaflet.js to React components). I am getting the maps from OpenTopoMap. This application is non-commercial and I have checked their terms of use to make sure I am not in violation.
I want users to be able to view a map and be able to add points and draw polygons on it (I already know how to do this part). Once they are done drawing on the map I want them to be able to save the map with whatever additions they have made. They should then be able to reopen it later and modify it.
The only way I have found to save the map is as a .png, which means it can't be edited when it is reopened.
Saving only the points/polygons and re-rendering them when a user reopens the map is an acceptable solution as long as the correct area of the map is shown when it is reopened, but I am not sure how I would go about storing this data. A user can have many maps, so solutions that only work for a single instance of map will not work in this case.
I am aware that what I have described here just duplicates the functionality of many other mapping applications. Once this part is figured out I plan to add extensive functionality that is specific to making geological maps. I have not described that functionality here because it is not relevant to my current question.
How can I save a map to PostgreSQL in a format that will allow it to be edited when reopened?
Instead of reinventing the wheel with some JSON column monstrosity look into PostGIS. Its an extension for Postgres that adds geospatial data types like points, lines and polygons. It also lets you write geospatial database queries like for example testing if a point is in a polygon or proximity searches.
For rails the the activerecord-postgis-adapter gem adds these database types:
:geometry -- Any geometric type
:st_point -- Point data
:line_string -- LineString data
:st_polygon -- Polygon data
:geometry_collection -- Any collection type
:multi_point -- A collection of Points
:multi_line_string -- A collection of LineStrings
:multi_polygon -- A collection of Polygons
This provides the building blocks to create models with geospatial attributes. Its not a magic wand that will let you stuff a map with doodles into Postgres and get something editable out and will require a significant effort in both research and implementation.
I use leaflet and leaflet.draw together to save the geoJSON from drawing polygons or dropping markers and save it to a field called coords in the database. There is a good example of it here: https://github.com/jeremygradisher/mapping-leaflet
It boils down to using leaflet.draw to draw the coordinates and then saving that data where you need it. Here is leaflet.draw: http://leaflet.github.io/Leaflet.draw/docs/leaflet-draw-latest.html
Here I am using leaflet.draw to draw on the map and then I stringify the data and add it to a field to be saved in the database.
<script>
// Initialize the FeatureGroup to store editable layers
var drawnItems = new L.FeatureGroup();
map.addLayer(drawnItems);
// Initialize and alter the draw control and pass it the FeatureGroup of editable layers
var drawControl = new L.Control.Draw({
draw: {
//These options make up the root object that is used when initializing the Leaflet.draw control.
position: 'topleft',
polygon: {
allowIntersection: false,
drawError: {color: '#00dd00', timeout: 1000
},
shapeOptions: {color: '#00dd00', weight: 1}, showArea: true},
polyline: false,
rectangle: {shapeOptions: {color: '#00dd00',weight: 1}},circle: false},
edit: {featureGroup: drawnItems}
});
map.addControl(drawControl);
//draw:created - Triggered when a new vector or marker has been created.
map.on('draw:created', function (e) {
var type = e.layerType,
layer = e.layer;
var shape = layer.toGeoJSON();
var shape_for_db = JSON.stringify(shape);
drawnItems.addLayer(layer);
//trying some things here
//enter in field to save to the database
document.getElementById('area_coords').value = shape_for_db;
});
As far as I understand you want to save complicated objects to the database. An user can draw lines on the map and can draw polygons and etc. Maybe using jsonb object for this problem can be your solution. Basically it's saving a JSON formatted field to database.
An example jsonb object can be like this.
{
"data": {
"type": "user_map",
"attributes": {
"user_id": "1",
"drawings": {
"points": [],
"lines": {},
"polygons": {}
}
}
}
}
You can both keep these information on user or on separate model with using has_many :maps on user model.
Links that can help you:
Example 1
Example 2
I would suggest not to think in terms of map (the rendering of spatial data) but in terms of data (a point/line/polygon with attributes). You would save each user data in tables, maybe have another map_config table that holds the map bounding box, name etc.
In you app, once you have authenticated the user, you give access to its map configurations (let him select the one to be shown) and associated data. You then display the map either using the raw vector data directly in Leaflet, Open Layers (or else), or you can pipe it through a geo server (Geoserver, Mapserver etc) for serving it as wms images, or wfs editable vector data. You zoom or restrict the displayed area to the one saved in the map configuration.
I have a 3 <tr></tr> in my table. user can edit them and on the save button I send the data to the server.
first is main and other all is child of the main. When someone click on new button a new child is created.
now I am thinking to maintain the information like this
var minf = {};
minf.main = $("#tr" + curSplidId).find('input,select').serialize();
res.each(function(n) {
var i = $(this).find('input,select').serialize();
minf[n] = i;
});
All I am trying to do is getting main object and array of childs in JsonResult, I have tried to use Dictionary for JSON.stringify values.
None of these works.
Someone please help me to get it done. Through my testing I found in a case it's sending me querystring in my minf object (I does Stringify) but I am not sure how to handle it on JSONResult as some kind of dictionary stuff where I can read it through the keys.
suppose you have a 3 tr. the best approach is to use a loop on all the tr and create a object same to the DTO that is using in action and make a list of it.
var MainList=[];
$('tr').each(function(){
var MainDTO={};
MainDTO.Column1=$(this).find('td').html();
MainDTO.Column2=$(this).find('td').html();
MainList.add(MainDTO)
});
and pass this MainList directly to action. no serialise required
I think for converting data to json and read that json on server. I make the whole process hard for JS and server to handle.
I change the strategy to serialize all the element and send it to server. it's work fine.
now if I need to read id then I can parse the id which is 3 and come in comma based values.
Assume we have simple data model with single entity User; simple tableView_friends with fetchedResultsController_friends for show users - friends.
Assume we have search bar for searching all (not only friends) users in service, and for every typed in it character we perform search request to server, which return to us somehow filtered by character User objects. Some of this objects can already be inside local database. By app logic we don't really must save all this results in local database forever (but ok, we can, we can clear local database time to time); on other hand, if we will perform any action on some searched user, we must store this user. We want to show list of searched user in other tableView_search with fetchedResultsController_search.
Question: should I use same context for fetchedResultsController_friends and fetchedResultsController_search? If no, how can I handle situation, when I wish to edit searched user, which already exists in database and probably already local edited? If yes, how can I setup predicate for fetchedResultsController_search (server perform its own logic for search by character, which can be changed) for show exactly same result as from server?
We recently implemented a search feature in our application and had a similar issue, We had local data in core data and also remote data from our API.
You have a few options that we explored:
Save your data into core data from the API as it is retreived and
then the fetched results controller will do the rest
Manage the merge of the data yourself, you can still use NSFetchedResults controller to an extent but need to do more work
We didn't want to save all of the information returned from the API unless it was needed (the user selected it), so we come up with a simple solution that worked for our app. This may not work directly for your app, you may need a completely different solution or change some of the things we done to suit.
Firstly, To explain what we are dealing with, we had a Article entity in core data which contains around 25 properties, the API returns article objects as JSON data with the same data.
What we decided to do was to create a class which represents a simple version of an article (just enough data to show in a list view and reference it later in the API or core data) which looked something like this:
class SearchResult: NSObject {
var id:String?
var title:String?
var imageUrl:String?
var url:String?
// core data entity
init(article:Article) {
self.id = content.contentId
self.title = content.title
self.featuredImageURL = content.absoluteImagePath()
self.urlAlias = content.urlAlias
self.publishedAt = content.publishedAt
}
init(articleDictionary:NSDictionary) {
self.id = articleDictionary.objectForKeyNotNull("id") as? String
self.title = articleDictionary.objectForKeyNotNull("title") as? String
self.url = articleDictionary.objectForKeyNotNull("url") as? String
if let imageUrl = articleDictionary.objectForKeyNotNull("imageUrl") as? String {
self.imageUrl = imageUrl
}
}
}
Now using this, we can create once of these from either the core data results or from the API results. Our tableview datasource is just an array
var dataSet = [SearchResult]()
We use the NSFectchResultsController delegate methods to add/remove/re-order core data elements from the dataSet after the initial load and when we get API data we'll do something like:
dataSet = Array(Set(apiResponseArray + dataSet))
This will take an array of SearchResult items from the API, merge them with the current result set and remove duplicates. casting to a set and then back to an array will give you an array of unique results as a Set is made of unique values only.
See this reference which should help with how the delegate methods would work
I must be missing something obvious - I am basically trying to do in v2, what I think is outlined in [this SO question], except that doesn't work in v2. Specifically, Gmaps.maps is no longer defined.
I've gotten as far as figuring that if I store the marker data array that's returned when I call addMarkers in the buildMaps callback, I can use the elements of that array to delete a marker.
If I'm storing a custom attribute in the JSON that I sent to addMarkers, I can then hold on to that JSON array as well, and query for that attribute, find the index, and then hide the marker with that index in the marker data array - here's what I mean, in pseudo-code:
json_array=generate_json();
handler.build_map({}, function() { window.marker_data=handler.addMarkers(); });
indexes=find_in_json(json_array, {"type":"hotel"});
marker_data[i].hide() for i in indexes;
But this means I have the same conceptual data in two places - is there a better way to do this that avoids managing the "model" of the marker in two separate arrays?
I understand your concern.
What I do is to merge data in this case, check http://apneadiving.github.io/ there is an example (check sidebar section)
var markers = handler.addMarkers(json_array);
_.each(json_array, function(json, index){
json.marker = markers[index];
});