Select to view content in your preferred language

How can I save the data info and drawing to database and reopen it later?

8694
7
Jump to solution
07-31-2013 01:08 PM
BillYuan
Emerging Contributor
I am new to this forum, did a quick search and could not find a good answer.

How can I save the polygon on map I just draw, as well as information and reopen it later? Do I have to store it in geodatabase?

thanks,
Bill
0 Kudos
1 Solution

Accepted Solutions
BenFousek
Deactivated User
Welcome to the forum Bill.

Saving map info and graphics is one of the more complex concepts in web mapping with the jsapi.  It takes some serious planning, coding and testing to get it working reliably. Here's a simple overview.

There's a few ways to save map parameters like extent, and graphics. The key is json.  Many of the esri classes have a toJson method which creates a json object, which is easily saved as plain text, and which can be used to easily recreate esri class objects. Take graphics for example:

Here's a snippet from a function that prepares map annotation (graphics) for saving.
var time = new Date().getTime().toString();

//javascript object with params for the save itself
//  and arrays for the various geometry types
var saveObj = {
  name: name,
  description: description,
  time: time,
  userId: userId,
  department, department,
  project: project,
  polygons: [],
  polylines: [],
  points: [],
  markers: [],
  text: []
};

//create json of each polygon object and push it to the polygon array
dojo.forEach(app.map.getLayer('gl_anno_polygon').graphics, function (g) {
  var obj = g.toJson();
  saveObj.polygons.push(obj)
});

//do the same polylines, points, etc

//convert js object to json
var save = dojo.toJson(saveObj);

//use ajax and some form of RDBMS to save json object

//parameters like name, userId, etc are also saved in separate fields in the database entry


Here's the json of 1 polygon.
{
  "geometry": {
    "rings": [[[-13715131.833534349, 5759372.32022381], [-13714845.194678271, 5759200.336910164], [-13715299.039533727, 5758751.269368976], [-13715514.018675784, 5759042.685539322], [-13715131.833534349, 5759372.32022381]]],
    "spatialReference": {
      "wkid": 102100
    }
  },
  "attributes": {
    "id": "1375306164892"
  },
  "symbol": {
    "color": [0, 115, 197, 51],
    "outline": {
      "color": [0, 115, 197, 255],
      "width": 1.5,
      "type": "esriSLS",
      "style": "esriSLSSolid"
    },
    "type": "esriSFS",
    "style": "esriSFSSolid"
  },
  "infoTemplate": {
    "title": "Polygon",
    "content": "<div style=\"line-height:1.5;\"><a style=\"cursor:pointer;text-decoration:none;\" onclick=\"app.anno.editStyle(${id}, 'polygon')\">Edit Polygon Style</a><br /><a style=\"cursor:pointer;text-decoration:none;\" onclick=\"app.anno.bringTop(${id}, 'polygon')\">Bring to Top</a><br /><a style=\"cursor:pointer;text-decoration:none;\" onclick=\"app.anno.sendBottom(${id}, 'polygon')\">Send to Bottom</a><br /><a style=\"cursor:pointer;text-decoration:none;\" onclick=\"app.anno.deleteGraphic(${id}, 'polygon')\">Delete</a></div>"
  }
}


On the flip side bring graphics back in by using ajax to retrieve saves by a specific user/department and display them in a data grid for the user to load a specific save.  Here's a snippet that adds polygons back to the map.

dojo.forEach(loadObj.polygons, function (polygon) {
  //the polygon param is the json for a single polygon
  //  simply creating a graphic with the json recreates it attributes, symbol and info template
  var graphic = new esri.Graphic(polygon);
  
  //array of all loaded graphics for zooming
  features.push(graphic);
  
  //graphic id to identify polygon to edit, delete, etc
  graphic.graphic_id = polygon.attributes.id;
  
  //set custom objects of the graphic used by custom print task
  graphic.graphic_atts = polygon.attributes;
  graphic.graphic_it = polygon.infoTemplate;
  
  //is the graphic a text symbol also for printing
  graphic.graphic_text = false;
  
  //add to the annotation polygon layer
  app.map.getLayer('gl_anno_polygon').add(graphic)
});


So there's some basics.

As for saving to a database.  I use php and mysql.  Super simple to set up and use. Php has great json functions that can be used for creating a json object for loading an entire applications for example.  But whatever you have and are comfortable with will work fine.  Go with a BLOB type and save yourself some hassle.

You may also try using HTML5's local storage.  I feel it's a little risky for saving graphics, but map saves, bookmarks, etc are usually ok.  If it's a business environment or folks can't risk losing data go with a database.

View solution in original post

7 Replies
BillYuan
Emerging Contributor
Not only I can, other signed users will be able to open it with latitude and longitude, with information I saved before, as well as the drawing on map. This is is my goal, anybody has suggestion?
0 Kudos
BenFousek
Deactivated User
Welcome to the forum Bill.

Saving map info and graphics is one of the more complex concepts in web mapping with the jsapi.  It takes some serious planning, coding and testing to get it working reliably. Here's a simple overview.

There's a few ways to save map parameters like extent, and graphics. The key is json.  Many of the esri classes have a toJson method which creates a json object, which is easily saved as plain text, and which can be used to easily recreate esri class objects. Take graphics for example:

Here's a snippet from a function that prepares map annotation (graphics) for saving.
var time = new Date().getTime().toString();

//javascript object with params for the save itself
//  and arrays for the various geometry types
var saveObj = {
  name: name,
  description: description,
  time: time,
  userId: userId,
  department, department,
  project: project,
  polygons: [],
  polylines: [],
  points: [],
  markers: [],
  text: []
};

//create json of each polygon object and push it to the polygon array
dojo.forEach(app.map.getLayer('gl_anno_polygon').graphics, function (g) {
  var obj = g.toJson();
  saveObj.polygons.push(obj)
});

//do the same polylines, points, etc

//convert js object to json
var save = dojo.toJson(saveObj);

//use ajax and some form of RDBMS to save json object

//parameters like name, userId, etc are also saved in separate fields in the database entry


Here's the json of 1 polygon.
{
  "geometry": {
    "rings": [[[-13715131.833534349, 5759372.32022381], [-13714845.194678271, 5759200.336910164], [-13715299.039533727, 5758751.269368976], [-13715514.018675784, 5759042.685539322], [-13715131.833534349, 5759372.32022381]]],
    "spatialReference": {
      "wkid": 102100
    }
  },
  "attributes": {
    "id": "1375306164892"
  },
  "symbol": {
    "color": [0, 115, 197, 51],
    "outline": {
      "color": [0, 115, 197, 255],
      "width": 1.5,
      "type": "esriSLS",
      "style": "esriSLSSolid"
    },
    "type": "esriSFS",
    "style": "esriSFSSolid"
  },
  "infoTemplate": {
    "title": "Polygon",
    "content": "<div style=\"line-height:1.5;\"><a style=\"cursor:pointer;text-decoration:none;\" onclick=\"app.anno.editStyle(${id}, 'polygon')\">Edit Polygon Style</a><br /><a style=\"cursor:pointer;text-decoration:none;\" onclick=\"app.anno.bringTop(${id}, 'polygon')\">Bring to Top</a><br /><a style=\"cursor:pointer;text-decoration:none;\" onclick=\"app.anno.sendBottom(${id}, 'polygon')\">Send to Bottom</a><br /><a style=\"cursor:pointer;text-decoration:none;\" onclick=\"app.anno.deleteGraphic(${id}, 'polygon')\">Delete</a></div>"
  }
}


On the flip side bring graphics back in by using ajax to retrieve saves by a specific user/department and display them in a data grid for the user to load a specific save.  Here's a snippet that adds polygons back to the map.

dojo.forEach(loadObj.polygons, function (polygon) {
  //the polygon param is the json for a single polygon
  //  simply creating a graphic with the json recreates it attributes, symbol and info template
  var graphic = new esri.Graphic(polygon);
  
  //array of all loaded graphics for zooming
  features.push(graphic);
  
  //graphic id to identify polygon to edit, delete, etc
  graphic.graphic_id = polygon.attributes.id;
  
  //set custom objects of the graphic used by custom print task
  graphic.graphic_atts = polygon.attributes;
  graphic.graphic_it = polygon.infoTemplate;
  
  //is the graphic a text symbol also for printing
  graphic.graphic_text = false;
  
  //add to the annotation polygon layer
  app.map.getLayer('gl_anno_polygon').add(graphic)
});


So there's some basics.

As for saving to a database.  I use php and mysql.  Super simple to set up and use. Php has great json functions that can be used for creating a json object for loading an entire applications for example.  But whatever you have and are comfortable with will work fine.  Go with a BLOB type and save yourself some hassle.

You may also try using HTML5's local storage.  I feel it's a little risky for saving graphics, but map saves, bookmarks, etc are usually ok.  If it's a business environment or folks can't risk losing data go with a database.
SteveCole
Honored Contributor
Great write up, Ben. Up voted. 😄
0 Kudos
BillYuan
Emerging Contributor
Hi Ben,

This is just what I need to know, a wonderful summary with great knowledge in my first day! 
Here is my plan based on your design. Envrionment: 1. Set up Arcgis server. 2. Set up a database server and a web server to host a HTML/javascript. In script,
1) render map.
2) draw polygons with freehand, and show info template retrieving from database with key from drawing.
3) Save the drawing as json text1, information as json text2, into database with a key as pair. Close the web session.
4). Reopen web session, retrieve data from database with json 1 and json 2, show map and layer, and drawing.

I believe this would work.
Do I have to setup a custom arcgis server in production to be able to render map and save data?
Do I have to use geodatabase to store the information?
thanks,
Bill
0 Kudos
BenFousek
Deactivated User
Do I have to setup a custom arcgis server in production to be able to render map and save data?
Do I have to use geodatabase to store the information?


You can create maps without access to arcgis server.

Any database will work.  You can certainly use a geodatabase with a published feature service to save data.
0 Kudos
BillYuan
Emerging Contributor
Thank you! In production, I can use enterprise arcgis server, and geodatabase or RDMS to reach my goal of saving/reopen drawing and info. At a start point,  I can create map with online arcgis server and use any database to store my data,  right?
0 Kudos
saurabhgupta2
Emerging Contributor

HI Ben,

I know its a old post but i need to do the same. I need to save the drawing (consisting of point , polygon, line , text) into database with user info  and retrieve the same when the same user log in.

I have just one question to the solution ..can we use feature service to store the drawings. If your ans is yes can you please provide some input for the same.

Thanks 

0 Kudos