A few days ago, I helped my friend do some map API research and recommended him to use Baidu bmap and Google GMAP APIs. Then I handed them over to him for help.
First, the precision printing system of the Degree certificate that I helped my primary school teacher last week was basically completed.
Second, I just got an internship with Baidu for the first month last year, and I am working on JavaScript. Therefore, I have some knowledge about bmap source code, API interface style, and documentation.
After one day and two nights, the basic functional requirements have been met (custom tagging, precise and fuzzy queries, personalized addition, right-click menu, etc:
Layout. the browser and its version are tested at the top, the data source and query functions are dynamically loaded on the left, and the bmap API is called on the right to implement its own application.
Knowledge Development: For JavaScript and CSS browser compatibility issues, please refer to my blog on Baidu space JavaScript and CSS browser compatibility Summary
Design Concept:The interface is a bmap API. Its internal functions adopt modular design, such as search module, custom addition, and right-click menu events. This design facilitates expansion and maintenance, and will be considered to be added to Google's GMAP later stage.
The following describes in detail how to design and implement internal functions.
1. Data Source format
The data source format is relatively regular. The specific format is as follows:
VaR DATA = [<br/> {ID: 100, point: "116.397128 | 39.916527", ADDR: "Zijin Tiancheng", mainflow: 3, subflow: 169.9, Press: 4, voltage: 13.3, flashflow: 1, isele: "mains available", time: "16:30:00" },< br/> {ID: 101, point: "116.422792 | 40.009471", ADDR: "Siri cun", mainflow: 3, subflow: 169.9, press: 4, voltage: 13.3, flashflow: 1, isele: "", time: "16:30:00" },< br/> {ID: 202, point: "116.484289 | 39.97936", ADDR: "Yangjia Dawan", mainflow: 13, subflow: 19.9, press: 14, voltage: 13.3, flashflow: 1, isele: "mains available", time: "16:30:00" },< br/> {ID: 303, point: "116.454494 | 39.964011", ADDR: "Zhao Peng", mainflow: 3, subflow: 69.9, press: 4, voltage: 13.3, flashflow: 1, isele: "mains available ", time: "16:30:00" },< br/> {ID: 404, point: "116.394601 | 39.987925", ADDR: "Wang Dian", mainflow: 3, subflow: 169.9, press: 4, voltage: 13.3, flashflow: 1, isele: "mains available", time: "16:30:00" },< br/> {ID: 500, point: "116.469899 | 39.87684", ADDR: "Liu cun", mainflow: 3, subflow: 169.9, press: 4, voltage: 13.3, flashflow: 1, isele: "mains available ", time: "16:30:00" },< br/> {ID: 501, point: "116.331292 | 39.949031", ADDR: "Xi Zi Ying", mainflow: 3, subflow: 169.9, press: 4, voltage: 13.3, flashflow: 1, isele: "mains available", time: "16:30:00" },< br/> {ID: 602, point: "116.374561 | 39.894302", ADDR: "Ma Jia Zhen", mainflow: 13, subflow: 19.9, press: 14, voltage: 13.3, flashflow: 1, isele: "mains available ", time: "16:30:00" },< br/> {ID: 703, point: "116.419527 | 39.945374", ADDR: "Daniel Mart", mainflow: 3, subflow: 69.9, press: 4, voltage: 13.3, flashflow: 1, isele: "mains available", time: "16:30:00" },< br/> {ID: 804, point: "116.394601 | 39.987925", ADDR: "mavericks xiawan", mainflow: 3, subflow: 169.9, press: 4, voltage: 13.3, flashflow: 1, isele: "mains available ", time: "16:30:00" },< br/> {ID: 905, point: "116.368099 | 39.942332", ADDR: "xujia reservoir", mainflow: 3, subflow: 169.9, press: 4, voltage: 13.3, flashflow: 1, isele: "mains available", time: "16:30:00"} <br/>];
Currently, data sources are stored and loaded in text format. As demand and applications expand, MySQL databases will be used for storage and extraction in the future.
2. dynamically load data sources(Left table)
Function init_middleleft () {<br/> var top_div = document. getelementbyid ("id_middle_left"); </P> <p> var table = document. createelement ("table"); <br/> table. setattribute ("border", 1); <br/> table. setattribute ("width", 280); <br/> for (VAR I = 0; I <data. length; I ++) {<br/> var TR = document. createelement ("TR"); </P> <p> var TD = document. createelement ("TD"); <br/> var STR = data [I]. ID; <br/> var MSG = document. createtextnode (STR); <br/> TD. appendchild (MSG); <br/> tr. appendchild (TD); </P> <p> TD = document. createelement ("TD"); <br/> STR = data [I]. ADDR; <br/> MSG = document. createtextnode (STR); <br/> TD. appendchild (MSG); <br/> tr. appendchild (TD); </P> <p> TD = document. createelement ("TD"); <br/> var IMG = document. createelement ("IMG"); <br/> IMG. src = ". /info.gif "; <br/> IMG. value = This. data [I]; <br/> IMG. onclick = function () {return click (this)}; // IMG. onclick = function ("Click (this. value) "); </P> <p> TD. appendchild (IMG); <br/> tr. appendchild (TD); </P> <p> table. appendchild (TR); <br/>}</P> <p> top_div.appendchild (table); <br/>}
Dynamic Loading of data sources on the left side:
3. Precise and fuzzy search(Regular Expression implementation)
// Search Class prototype <br/> function searchclass (data) {<br/> This. datas = data; <br/>}</P> <p> // set the data source <br/> searchclass. prototype. setdata = function (data) {<br/> This. datas = data; <br/>}</P> <p> // Remove string spaces <br/> searchclass. prototype. trim = function (STR) {<br/> If (null = Str) {<br/> STR = ""; <br/>} else {<br/> STR = Str. tostring (); <br/>}</P> <p> return Str. replace (/(^ [\ s \ t \ xa0 \ u3000] +) | ([\ U3 000 \ xa0 \ s \ t] + $)/g ,""); <br/>}</P> <p> // search prototype query module <br/> // rule = {ID: "ID", key: "keyword ", query: "single | more", show: "One | all"} <br/> searchclass. prototype. search = function (rule) {<br/> If (null = This. datas) {<br/> alert ("the data source does not exist! "); <Br/> return false; <br/>}</P> <p> If (" "= This. trim (rule) | "" = This. trim (rule. ID) | "" = This. trim (rule. key) | "" = This. trim (rule. query) {<br/> alert ("Please specify the content to search! "); <Br/> return false; <br/>}</P> <p> var reval = []; // return value, object array type <br/> var datas = This. datas; // Search Class, member variable <br/> me = This; // global this, me in getdata </P> <p> // Add query results <br/> var adddata = function (data) {<br/> reval. push (data); <br/>}</P> <p> // obtain the query data source string <br/> var getdata = function (data, ID) {<br/> VaR _ id = me. trim (ID); <br/> var d = "data"; <br/> If (0 = _ id. length) {<br/> return data; <br/>} else {<br/> D + = '["' + _ ID + '"]'; <br/> return eval (d ); <br/>}</P> <p> // search traversal <br/> for (VAR I = 0; I <datas. length; I ++) {<br/> var DATA = datas [I]; <br/> var d = getdata (data, rule. ID); <br/> var dreg = new Regexp (this. trim (rule. key); </P> <p> If ("one" = rule. show) {// display query tag <br/> If ("single" = rule. query & D = rule. key) {// precise query (single) <br/> adddata (data); <br/>}else if ("more" = rule. query & dreg. test (D) {// fuzzy query (Regular Expression implementation) <br/> adddata (data ); <br/>}< br/>} else if ("all" = rule. show) {// display all tags <br/> adddata (data ); <br/>}</P> <p> // return result <br/> return reval; <br/>}
4. Mark the query result
// Mark the query result <br/> window. addmarker = function (data_a) {<br/> map. clearoverlays (); // first clear the existing tag </P> <p> // traverse the query result data (data_a) <br/> for (VAR I = 0; I <data_a.length; I ++) {<br/> // obtain coordinates (longitude and latitude) and display them on Map <br/> var PX = data_a [I]. point. split ("|") [0]; <br/> var py = data_a [I]. point. split ("|") [1]; </P> <p> var point = new bmap. point (PX, Py); <br/> var marker = new bmap. marker (point); <br/> map. addoverlay (Marker); <br/> // marker. enabledragging (true); </P> <p> // generate the tag information (table) <br/> var content = "<Table> "; <br/> content = content + "<tr> <TD> device No.:" + data_a [I]. ID + "</TD> </tr>"; <br/> content = content + "<tr> <TD> installation location:" + data_a [I]. ADDR + "</TD> </tr>"; <br/> content = content + "<tr> <TD> Primary table traffic:" + data_a [I]. mainflow + "</TD> </tr>"; <br/> content = content + "<tr> <TD> sub-Table traffic:" + data_a [I]. subflow + "</TD> </tr>"; <br/> content = content + "<tr> <TD> Pipe Network Pressure:" + data_a [I]. press + "</TD> </tr>"; <br/> content = content + "<tr> <TD> device voltage:" + data_a [I]. voltage + "</TD> </tr>"; <br/> content = content + "<tr> <TD> instantaneous traffic:" + data_a [I]. flashflow + "</TD> </tr>"; <br/> content = content + "<tr> <TD> mains:" + data_a [I]. isele + "</TD> </tr>"; <br/> content = content + "<tr> <TD> record time:" + data_a [I]. time + "</TD> </tr>"; <br/> content + = "</table> "; </P> <p> // capture tag click events and display information <br/> // function closure, always executed <br/> (function () {<br/> var infowindow = new bmap. infowindow (content); <br/> marker. addeventlistener ("click", function () {<br/> This. openinfowindow (infowindow); <br/>}) () <br/>}< br/>}
MARK:
5. Right-click menu implementation
// Add the right-click menu <br/> var contextmenu = new bmap. contextmenu (); <br/> var txtmenuitem = [<br/> {<br/> text: "zoom in", <br/> callback: function () {map. zoomin ()} <br/>}, <br/>{< br/> text: "zoom out", <br/> callback: function () {map. zoomout ()} <br/>}, <br/>{< br/> text: 'view Beijing', <br/> callback: function () {map. centerandzoom ("Beijing") }< br/>}, <br/>{< br/> text: 'place to Max', <br/> callback: function () {map. zoomto (18) }< br/>}, <br/>{< br/> text: 'Get the coordinate of the version', <br/> callback: function (P) {<br/> var PX = P. LNG; <br/> var py = P. lat; <br/> alert ("coordinates: \ N longitude:" + px + "; \ N latitude:" + Py ); <br/>}< br/>}, <br/>{< br/> text: 'add the store annotation ', <br/> callback: function (P) {<br/> var marker = new bmap. marker (P), PX = map. pointtopixel (p); <br/> map. addoverlay (Marker); <br/> marker. enabledragging (true); <br/>}< br/>]; </P> <p> // traverse menu items, add to menu <br/> for (VAR I = 0; I <txtmenuitem. length; I ++) {<br/> contextmenu. additem (New bmap. menuitem (txtmenuitem [I]. text, txtmenuitem [I]. callback, 100); <br/> if (I = 1 | I = 3) {<br/> contextmenu. addseparator (); <br/>}< br/> map. addcontextmenu (contextmenu); // Add a menu to map
Menu:
6. Fuzzy search results
On the left, enter "1" for fuzzy match query and display query results.
Output 3 tag results on the right
Check: 100, 101, and 501 all contain the query keyword "1". The query result is correct.
7. Focus on details and improve the experience
Some details are also taken into account during implementation. Here are two examples:
A. An automatic prompt is displayed in the input box.
When the user does not enter the image, the input box displays the prompt "input ID". When the user clicks the mouse, the prompt is automatically cleared (is it like Ajax watermark effect? haha)
In fact, its internal implementation is not complicated, but the casual design reflects the humanization.
Specific implementation (Onmousedown and onmouseout)
<Textarea readonly name = "code" class = "JavaScript" style = "margin-top: 4px; margin-Right: 0px; margin-bottom: 4px; margin-left: 0px; background-color: RGB (240,240,240 ); "> <input type =" text "name =" keyword "id =" id_keyword "value =" input ID "onmousedown =" clearkeyword ('keyword ') "<br/> onmouseout =" showkeyword ('keyword') "/> </P> <p> </textarea><textarea readonly name="code" class="javascript" style="margin-top: 4px; margin-right: 0px; margin-bottom: 4px; margin-left: 0px; background-color: rgb(240, 240, 240); ">// Press the mouse to clear the message. <br/> function clearkeyword (keyword) {<br/> var input = document. getelementsbyname (keyword); <br/> input [0]. value = ""; // clear prompt </P> <p >}</P> <p> // move the mouse. if the content is empty, <br/> function showkeyword (keyword) {<br/> var input = document. getelementsbyname (keyword); <br/> VaR value = input [0]. value; <br/> If ("" = value) {// determines whether it is null <br/> input [0]. value = "input ID"; <br/>}< br/>}</textarea>
B. Highlight the query on the left
After you click the query icon, the background color of this column is highlighted to make it clear to you.
ImplementationCodeAs follows:
// Click the search small icon on the left <br/> function click (OBJ) {<br/> // clear all TD elements first, erase the footprints highlighted last time <br/> var td_a = document. getelementsbytagname ("TD"); <br/> for (VAR I = 0; I <td_a.length; I ++) {<br/> td_a [I]. setattribute ("bgcolor", "# ffffff"); <br/>}</P> <p> // highlight the Query Information <br/> obj. parentnode. setattribute ("bgcolor", "# ff0000"); </P> <p> var data_a = []; <br/> var DATA = obj. value; <br/> data_a.push (data); <br/> addmarker (data_a); <br/>}
Okay, that's it.
In the future, I plan to extend Google's map API to achieve the free choice of Baidu and Google Maps.
Later, we will try to add newer and cooler technologies to create some HTML5 and css3 advanced application special effects.