|
POST
|
Interesting concept, except I don't want to try to manage multiple MXD/MSD files or lump things together, the organization we have makes sense within the facilities we manage. I totally understand. What David Peters said is from the performance point of view in term of system design and network.
... View more
04-28-2011
04:50 AM
|
0
|
0
|
4000
|
|
POST
|
I am still not getting the same results with the group_layer_id issue, however, the bigger challenge right now is the fact that the setVisibleLayers method crashes the service with a large number of layers in the array (500+ for a large area map that is our production service representing 80 facilitieis across 6 counties). It creates a cache image of the current screen when I toggle a layer, then if I zoom-out / pan, all I get is that cached image of the dynamic service with no-redraw / refresh. All other services respond correctly. I agree, some insight/input from ESRI staff would be great on both issues. One thing i remembered from reading the document (David Peter's "Building a GIS: System Architecture Design Strategies for Managers") is that avoid to put too many layers in a one map services and tried to split layers into several map services.
... View more
04-27-2011
12:54 PM
|
0
|
0
|
4000
|
|
POST
|
From my testing I have found different results than what your post would suggest, for example: Sample MapService Facility Layer(0) - Group Layer Building(1) - Feature Class Pipeline(2) - Feature Class Encasement(3) - Feature Class Another Facility Layer(4) - Group Layer Vaults(5) - Feature Class Fittings(6) - Feature Class Easements(7) - Feature Class All within one dynamic map service. Scenario One:
var vL = [0,1,2,3,4,5,6,7]; -Visible Layer Array
var layer_id_index = dojo.indexOf(vL, 2);
if (layer_id_index != -1)
vL.splice(layer_id_index, 1);
dynamic_layer_data.setVisibleLayers(vL);
Results: No change in visible layers. Modification to Code
var viz_layer = [1,2,3,5,6,7]; - Remove the GroupLayer ID
Results: Pipeline Layer is �??Hidden�?�. I have found that including the GroupLayer ID�??s in the visible layer array causes the setVisibleLayers method to fail (ie. [0,1,2] is a not-valid/illegal and [1,2] is a valid/legal array) Scenario Two: If the dynamic_layer_data contains a large list of layers (I have tested against 633 with divided across 75 group layers), the same code above under the modified scenario does not work. I could painstaking try to find the �??cut-off�?� point but would like to know if there is a definitive (ESRI) answer on if the setVisibleLayers method works on an infinite number of layers or if it can only handle 50, 100, etc. I went back looking at my code and my notes. i have done it in silverlight/wpf api which is almost identical to js api in terms of visibility properties and methods. What i said here is exactly what my notes said. So I tested this issue using JS api and an esri map services: http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer. You are largely right on this expect I found out that whehter putting group layer id in visible id array or not doesn't make any different (visible = [0, 1, 3, 4, 5] vs visible = [0, 1, 2, 3, 4, 5] -2 is the group layer). I am very interested in ESRI or someone's input on this.
... View more
04-27-2011
11:25 AM
|
0
|
0
|
4000
|
|
POST
|
Thanks for your help. How to the conversion from State Plane feet to lon/lat before adding your result to the Google Map? Like i said the best solution is convert your geocode reference layer to 4326. then publish your locator service and problem solved. If this solution is not feasible, Then you can do the following: 1. Access you actual address locator through Arcatalog->Address Locator Properties. Check X and Y coordinates under Output Fields. 2. Refresh your locator service. 3. In your code, after you do the geocode, reproject your addressCandidate to SR 4326. Here is the code snippets on top your code just give you some ideas: var gOverlays = null; var geometry; function initialize() { gmap = new GMap2(document.getElementById('gmap')); gmap.addMapType(G_NORMAL_MAP); gmap.addMapType(G_SATELLITE_MAP); gmap.addControl(new GLargeMapControl()); gmap.addControl(new GMapTypeControl()); gmap.setCenter(new GLatLng(29.76, -95.36),12); // Redlands (Point) mapExtension = new esri.arcgis.gmaps.MapExtension(gmap); geometry = new esri.arcgis.gmaps.Geometry("http://sampleserver1.arcgisonline.com/arcgis/rest/services/Geometry/GeometryServer"); locator = new esri.arcgis.gmaps.Locator("http://gisapps.houstongims.org/ArcGIS/rest/services/Address_Locator_Zip_Appr_HCAD_Parcel2009/GeocodeServer"); } function findAddress() { mapExtension.removeFromMap(gOverlays); var address = new Object(); address.Street="611 Walker"; address.Zone= "77002"; var outFields = ["Street", "X", "Y"]; locator.addressToLocations(address, outFields, false, mycallback); } function mycallback(addressResults) { var address = addressResults.addressCandidates[0]; var params = new esri.arcgis.gmaps.ProjectParameters(); params.geometries = [ { x: address.attributes.X, y: address.attributes.Y } ]; params.inSpatialReference = 2278; params.outSpatialReference = 4326; params.geometryType = "esriGeometryPoint"; geometry.project(params, function(projectResults) { // marker will be your geocoded point var marker = projectResults.geometries[0][0]; ..... then add it the map or do something. }); } Hop it will help
... View more
04-27-2011
06:45 AM
|
0
|
0
|
740
|
|
POST
|
So I started playing with a simple custom legend by trying the following code against a DynamicLayer:
var vL = df_layer_data.visibleLayers;
var layer_id_index = dojo.indexOf(vL, 2);
if (layer_id_index != -1)
vL.splice(layer_id_index, 0);
else
vL.push(2);
df_layer_data.setVisibleLayers(vL);
I fully expected to see Layer #2 (a pipeline layer in this case) toggle visibility. However, it didn't. After a few minutes of "hacking", I found the problem, the service is a compilation of grouped feature classes and the setVisibleLayers call doesn't like having the ID's for the group layers in the array. If setVisibleLayers (and maybe other functions) doesn't like and can't handle group layers, why does visibleLayers return them? There might just be a great answer to that and would really like to hear it so I can learn something new today (or whenever). You are on the right track. Just be aware of a couple of things. Suppose you have a parent layer 0, and a couple of sublayer 1 and 2. If you set the parent layer 0 visible, you still have to set the visibility of layer 1 and 2 for them to show or not show - these visible layer array [0,1] or [0,2] or [0,1,2] are legal, while those - [1] or [2] or [1,2] are illegal. If you set parent layer 0 not visible, then neither 1 nor 2 should in visible layer array. You can use LayerInfo's parentLayerId and subLayerIds properties to manipulate the situation.
... View more
04-27-2011
06:12 AM
|
0
|
0
|
4000
|
|
POST
|
Are you sure response is a string? What does the rest of your esri.request() code look like? In practice, especially when talking to ArcGIS Server endpoints, I don't think there are many (any?) times you'd want text over json. Why mess around with wrapping a response in parens and calling eval() when the server can return jsonp? you can test it on my sample code to see if response is a string or not. The point here is that response is a lightweight string instead of an JSON Object. Because I specify url with f=json (or f=pjson), the returned response string is a json text. So you can safely use eval() to convert it in order to get extent. . You can also use other methods to fetch geometres from the response string if you like. Esri.request is efficient to request raw data(.txt, .xml), or, in this case, extent (even thought not exactly) from the server especially if you don't need Json Object to return.
... View more
04-25-2011
12:17 PM
|
0
|
0
|
1767
|
|
POST
|
True, we're not likely to find a solution to OP's question/problem in this thread. But I'd like to continue this discussion as I think we still need to clarify for anyone else who comes across this thread. A featureSet, in the context of the JavaScript API and as delivered to the client, is a JSON object. Let's look at this from another angle. How about we talk about this in terms of the REST API? If you want features from a layer in a map service, how do you get them? You use the query endpoint. If you use the endpoint via the JavaScript API's QueryTask (recommended) or through esri.request, you are getting back JSON (as long as you specify f=json when using esri.request). in my code: function requestSucceeded(response, io) response is a string. u can use alert(response) while in function queryonComplete(featureSet) featureSet is an object..
... View more
04-25-2011
10:52 AM
|
0
|
0
|
1767
|
|
POST
|
@hzhu As you request more features (using either esri.request or a queryTask), the response size will grow. If the server only returned the extent of the features that satisfy a request, then the response size will be consistent if you ask for 10 or 1000 features. To my knowledge, there's not an out of the box way to get just a bounding box for features that satisfy a request w/o sending all of the geometries to the client. How is the return value of esri.request different than a queryTask? The JavaScript syntax for working with them differs but both fetch plain text from the server (you can verify this via firebug or chrome's dev tools) that is then turned into JavaScript objects on the client. Handle as "text" (json text in this case) is difinitely differently than handle as "featureset" (Object). Yes there is not way to get the extent directly. But wrap a jason text is different and lighter than wrap featureset object in a http resonse object, and at least, is close to a solution. firebug's debug shows the response object in a text format for display, internally primitive type (string) and object type are delievered and handled differently. There is no point to argue here than try to find a solution to help...
... View more
04-25-2011
09:23 AM
|
0
|
0
|
3930
|
|
POST
|
I am coding a Javascript application with ArcGIS Google Map Extension. I have my own geocoder which has spatial reference WKID 2278, not 4326. Results don't display in Google map. it works good for silverlight application by convert result to 4326 when display and online service test successful. but I don't know what should be done in this case. Please help! If you looked at Google Map API, Point or location -GLatLng is specified with lon/lat even though the Google Map is in WKID 102100. I would suggest that you covert your locator layer to WKID 4326. Otherwise you will have to do some covertion from State Plane feet to lon/lat before adding your result to the Google Map.
... View more
04-25-2011
05:55 AM
|
0
|
0
|
740
|
|
POST
|
@hzhu that still brings all the geometries across the wire, which is what OP is trying to avoid. Using esri.request all the geometries returns as text or strings (Json text), which is the basic format of the response and fundamentally different form what is return from querytask's callback, which is wraped by server as an object. I don't know what is OP try to avoid if he want something more simple back from the server than a string and convert it to geometries on client browser.
... View more
04-24-2011
05:27 PM
|
0
|
0
|
3930
|
|
POST
|
Hi swingley, thanks for the reply. I can't use static json files because the geometries in my web application are dynamic (i.e they can be added in an adhoc manner). if you use esri.request to set a url with f=json format. you will get a featurset form server in json text format. Then it is easy to get extent from it. Here is a code you can try: var urlStr = "http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Specialty/ESRI_StateCityHighway_USA/MapServer/1/query?where=STATE_NAME='Florida'&f=json"; var url = esri.urlToObject(urlStr); var requestHandle = esri.request({ url: url.path, content: url.query, handleAs: "text", load: requestSucceeded, error: requestFailed }, {useProxy:true}); .... function requestSucceeded(response, io) { var featureSet = eval('(' + response + ')'); var extent =esri.graphicsExtent(featureSet.features); }
... View more
04-22-2011
12:55 PM
|
0
|
0
|
3930
|
|
POST
|
I have tried a few ways to activate my buffer query with a button, but (being a newbie), I have failed. The buffer I have set up works, but since I'm also going to have an identify button on the page, I need to have the user activate the buffer query with a button as well. Otherwise the buffer will run everytime the user clicks to identify a feature. I know how to toggle an identify task off and on, but I can't figure out how to control the buffer. Anyhelp would be appreciated. Here's the code <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <meta http-equiv="X-UA-Compatible" content="IE=7" /> <!--The viewport meta tag is used to improve the presentation and behavior of the samples on iOS devices--> <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"/> <title>QueryTask with query geometry from another task</title> <link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/2.1/js/dojo/dijit/themes/claro/claro.css"> <script type="text/javascript" src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=2.1"></script> <script type="text/javascript"> dojo.require("esri.map"); dojo.require("esri.tasks.query"); dojo.require("esri.tasks.geometry"); var bufferqueryTask; /*Initialize map, buffer, & query params*/ function init() { var startExtent = new esri.geometry.Extent({"xmin":-28364141.57017,"ymin":-2803495.15887,"xmax":12597044.415,"ymax":21320884.31716,"spatialReference":{"wkid":3089}}); var map = new esri.Map("mapDiv", {extent:startExtent, wrapAround180:true}); //listen for when map is loaded and then add query functionality dojo.connect(map, "onLoad", initFunctionality); dojo.connect(map, "onLoad", function() { map.disableDoubleClickZoom(); }); //after map loads, connect to listen to mouse move & drag events dojo.connect(map, "onMouseMove", showCoordinates); var streetMap = new esri.layers.ArcGISDynamicMapServiceLayer("http://dingo.gapanalysisprogram.com/ArcGIS/rest/services/PADUS/PADUS_status/MapServer"); map.addLayer(streetMap); var gap = new esri.layers.ArcGISDynamicMapServiceLayer("http://dingo.gapanalysisprogram.com/ArcGIS/rest/services/PADUS/Ancillary/MapServer"); map.addLayer(gap); } function initFunctionality(map) { //identify proxy page to use if the toJson payload to the geometry service is greater than 2000 characters. //If this null or not available the buffer operation will not work. Otherwise it will do a http post to the proxy. //esriConfig.defaults.io.proxyUrl = "/arcgisserver/apis/javascript/proxy/proxy.ashx"; //esriConfig.defaults.io.alwaysUseProxy = false; //esriConfig.defaults.io.proxyUrl = "/arcgisserver/proxy/proxy.ashx"; //esriConfig.defaults.io.proxyUrl = "http://www.gap.uidaho.edu/proxy_ags.jsp"; esriConfig.defaults.io.proxyUrl = "http://dingo.gapanalysisprogram.com/proxy/proxy.ashx"; //esri.config.defaults.io.proxyUrl = "http://www.gap.uidaho.edu/proxy.php"; esriConfig.defaults.io.alwaysUseProxy = false; //Geometry Service Endpoint var gsvc = new esri.tasks.GeometryService("http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer"); bufferqueryTask = new esri.tasks.QueryTask("http://dingo.gapanalysisprogram.com/ArcGIS/rest/services/PADUS/PADUS_status/MapServer/0"); // Query var bufferquery = new esri.tasks.Query(); // +++++Listen for map onClick event+++++ dojo.connect(map, "onClick", function(evt) { map.graphics.clear(); var params = new esri.tasks.BufferParameters(); params.geometries = [ evt.mapPoint ]; // Buffer in linear units such as meters, km, miles etc. params.distances = [ dojo.byId('bufferDistance').value ]; params.unit = esri.tasks.GeometryService.UNIT_STATUTE_MILE; params.bufferSpatialReference = new esri.SpatialReference({"wkid": 3089}); params.outSpatialReference = new esri.SpatialReference({"wkid": 3089}); gsvc.buffer(params); dojo.byId('messages').innerHTML = "<b>Creating Buffer Using Geometry Service...</b>"; }); // +++++Listen for GeometryService onBufferComplete event+++++ dojo.connect(gsvc, "onBufferComplete", function(geometries) { var symbol = new esri.symbol.SimpleFillSymbol("none", new esri.symbol.SimpleLineSymbol("dashdot", new dojo.Color([255,0,0]), 2), new dojo.Color([255,255,0,0.25])); var graphic = new esri.Graphic(geometries[0],symbol); map.graphics.add(graphic); bufferquery.returnGeometry = true; bufferquery.outFields = ["P_Des_Nm","P_Loc_Nm","Own_Name","Mang_Name"]; bufferquery.outSpatialReference = map.spatialReference; bufferquery.geometry = geometries[0]; //query.where = "quadrangle_name='Adairville'" bufferqueryTask.execute(bufferquery); dojo.byId('messages').innerHTML = "<b>Executing Query with Result Buffer Geometry...</b>"; }); // +++++Listen for QueryTask executecomplete event+++++ dojo.connect(bufferqueryTask, "onComplete", function(fset) { //create symbol for selected features var symbol = new esri.symbol.SimpleMarkerSymbol(); symbol.style = esri.symbol.SimpleMarkerSymbol.STYLE_SQUARE; symbol.setSize(8); symbol.setColor(new dojo.Color([255,255,0,0.5])); //var infoTemplate = new esri.InfoTemplate("Block: ${BLOCK}", "${*}"); var resultFeatures = fset.features; for (var i=0, il=resultFeatures.length; i<il; i++) { console.log(resultFeatures); var graphic = resultFeatures; graphic.setSymbol(symbol); map.graphics.add(graphic); } var pareas = returnRecordNums(fset); var r = ""; r = "<b>The protected areas within the buffer are <i>" + pareas + "</i>.</b>"; dojo.byId('messages').innerHTML = r; }); } function returnRecordNums(fset){ var features = fset.features; var pas = ""; for (var x = 0; x < features.length; x++) { pas = pas + ", " + features .attributes['P_Des_Nm']; } return pas; } function showCoordinates(evt) { //get mapPoint from event var mp = evt.mapPoint; //display mouse coordinates dojo.byId("info").innerHTML = mp.x + ", " + mp.y; } dojo.addOnLoad(init); </script> </head> <body class="claro"> Zoom to area and click on map to select protected areas within the buffered circle.<br/> Buffer distance (in miles): <input type="text" id="bufferDistance" value="1" size="5" onkeydown="if (event.keyCode == 13) document.getElementById('btnSearch').click()"/> <form action=""> Buffer distance : <input type="text" id="bufferDistance" value="1" /> <input type="button" value="Get Details" onclick="execute(dojo.byId('b').value);" /> </form> <div id="job"></div> <div id="mapDiv" style="width: 850px; height:500px; position:relative;"> <span id="info" style="position:absolute; right:25px; bottom:5px; color:#000; z-index:50;"></span> </div> <span id="messages"></span> </body> </html> The best way to do this is to create a delegate to handle identify and buffer events. Here is how you do it: //globle variable (could be a boolean, int or string): var actionMode ="identify"; //default ...... dojo.connect(map, "onClick", doActionAccordingly); ...... function doActionAccordingly(evt) { switch (actionMode) { case "identify": .... identify go here break; case "bufferQuery": .... buffer query goes here // remember reset actionMode ="identify" after finish buffer query break; ........ } } function bufferBtn_onclick() { //set action mode to buffer actionMode ="bufferQuery"; } Hope it will help
... View more
04-22-2011
11:49 AM
|
0
|
0
|
476
|
|
POST
|
Where can I find the original sample code? I couldn't find it in the javascript api samples. Thanks. All i have to add to the sample code is the following. So make your own judgement what is best for you. dojo.connect(map.graphics, "onMouseDown", holdGraphic); dojo.connect(map, "onMouseDragEnd", releaseGraphic); ..... function holdGraphic(evt) { map.disablePan(); theGraphic = evt.graphic; theGraphic.setSymbol(highlightSymbol); } function releaseGraphic(evt) { theGraphic.geometry = evt.mapPoint; theGraphic.setSymbol(defaultSymbol); map.disablePan(); }
... View more
04-22-2011
04:41 AM
|
0
|
0
|
3649
|
|
POST
|
Where can I find the original sample code? I couldn't find it in the javascript api samples. Thanks. The orignal sample is at: http://help.arcgis.com/en/webapi/javascript/arcgis/demos/graphics/graphics_extent_query.html. I just changed it a liitle bit for Drag and drop purpose.
... View more
04-21-2011
09:01 AM
|
0
|
0
|
3649
|
|
POST
|
Hello All, We have our application developed in .Net using WebADF Map controls. I need help on how i can implement the "drag graphics point" functionality in our application that built using WebADF.Net controls. I found that using dojo we can implement drag/drop but i am not able to use dojo with Map control of WebADF. I also want to know what are the different approach/implementation for drag/drop graphics on Map? Any help will be appreciated. One similar post that never replied : http://forums.esri.com/Thread.asp?c=158&f=2396&t=286884 Thanks Lala Rabari In JS api it is very easy to drag and drop a gaphic by invoking a couple of event. Here is the sample page from ESRI, I just change a little bit. Try it youself if you are interested. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <meta http-equiv="X-UA-Compatible" content="IE=7" /> <!--The viewport meta tag is used to improve the presentation and behavior of the samples on iOS devices--> <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"/> <title>Draw and drop Point</title> <link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/2.2/js/dojo/dijit/themes/claro/claro.css" /> <script type="text/javascript" src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=2.2"></script> <script type="text/javascript"> dojo.require("esri.map"); dojo.require("esri.toolbars.draw"); dojo.require("esri.tasks.query"); //global variables var map, defaultSymbol, highlightSymbol, resultTemplate; var theGraphic; function init() { //create map, set initial extent and disable default info window behavior map = new esri.Map("map", { extent: esri.geometry.geographicToWebMercator(new esri.geometry.Extent(-125.90, 44.60, -114.65, 50.22, new esri.SpatialReference({wkid:4326}))), showInfoWindowOnClick:false }); dojo.connect(map, "onLoad", function(map) { dojo.connect(dijit.byId('map'), 'resize', resizeMap); }); map.addLayer(new esri.layers.ArcGISTiledMapServiceLayer("http://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer")); //initialize symbology defaultSymbol = new esri.symbol.SimpleMarkerSymbol().setColor(new dojo.Color([0,0,255])); highlightSymbol = new esri.symbol.SimpleMarkerSymbol().setColor(new dojo.Color([255,0,0])); //initialize & execute query var queryTask = new esri.tasks.QueryTask("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Specialty/ESRI_StatesCitiesRivers_USA/MapServer/0"); var query = new esri.tasks.Query(); query.where = "STATE_NAME = 'Washington'"; query.outSpatialReference = {wkid:102100}; query.returnGeometry = true; query.outFields = ["CITY_NAME"]; queryTask.execute(query, addPointsToMap); //info template for points returned resultTemplate = new esri.InfoTemplate("City", "<tr><td>${CITY_NAME}</tr></td>"); } function resizeMap() { var resizeTimer; clearTimeout(resizeTimer); resizeTimer = setTimeout(function() { map.resize(); map.reposition(); }, 500); } //add points to map and set their symbology + info template function addPointsToMap(featureSet) { dojo.forEach(featureSet.features,function(feature){ map.graphics.add(feature.setSymbol(defaultSymbol).setInfoTemplate(resultTemplate)); }); dojo.connect(map.graphics, "onMouseDown", holdGraphic); dojo.connect(map, "onMouseDragEnd", releaseGraphic); } function holdGraphic(evt) { map.disablePan(); theGraphic = evt.graphic; theGraphic.setSymbol(highlightSymbol); } function releaseGraphic(evt) { theGraphic.geometry = evt.mapPoint; theGraphic.setSymbol(defaultSymbol); map.disablePan(); } //find all points within argument extent function findPointsInExtent(extent) { var results = []; dojo.forEach(map.graphics.graphics,function(graphic){ if (extent.contains(graphic.geometry)) { graphic.setSymbol(highlightSymbol); results.push(graphic.getContent()); } //else if point was previously highlighted, reset its symbology else if (graphic.symbol == highlightSymbol) { graphic.setSymbol(defaultSymbol); } }); //display number of points in extent dojo.byId("inextent").innerHTML = results.length; //display list of points in extent dojo.byId("results").innerHTML = "<table><tbody>" + results.join("") + "</tbody></table>"; } dojo.addOnLoad(init); </script> </head> <body class="claro"> Draw an Extent on the map to find all points within this extent <!-- map div --> <div id="map" style="width:800px; height:400px; border:1px solid #000;"></div> <br /> </body> </html>
... View more
04-20-2011
01:25 PM
|
0
|
0
|
3649
|
| Title | Kudos | Posted |
|---|---|---|
| 1 | 04-11-2011 12:16 PM | |
| 1 | 05-25-2017 08:26 AM | |
| 1 | 06-02-2017 07:37 AM | |
| 1 | 06-28-2011 07:02 AM | |
| 1 | 06-12-2017 10:10 AM |
| Online Status |
Offline
|
| Date Last Visited |
10-01-2024
09:57 PM
|