diff --git a/base/aaa/user.go b/base/aaa/user.go index d55c1376..d9570dfb 100644 --- a/base/aaa/user.go +++ b/base/aaa/user.go @@ -18,6 +18,7 @@ const ( AVATAR = "avatar" GENDER = "gender" MOBILE = "mobile" + SECRET = "secret" CITY = "city" COUNTRY = "country" diff --git a/base/web/spide.go b/base/web/spide.go index b5818186..dc57e4d8 100644 --- a/base/web/spide.go +++ b/base/web/spide.go @@ -184,7 +184,8 @@ func _spide_save(m *ice.Message, action, file, uri string, res *http.Response) { switch action { case SPIDE_RAW: if b, _ := ioutil.ReadAll(res.Body); strings.HasPrefix(res.Header.Get(ContentType), ApplicationJSON) { - m.Echo(kit.Formats(kit.UnMarshal(string(b)))) + // m.Echo(kit.Formats(kit.UnMarshal(string(b)))) + m.Echo(string(b)) } else { m.Echo(string(b)) } @@ -257,11 +258,12 @@ const ( CLIENT_ORIGIN = "client.origin" CLIENT_URL = "client.url" - OPEN = "open" - MAIN = "main" - FULL = "full" - LINK = "link" - MERGE = "merge" + OPEN = "open" + MAIN = "main" + FULL = "full" + LINK = "link" + MERGE = "merge" + VENDOR = "vendor" QS = "?" ) diff --git a/core/chat/location/amap.go b/core/chat/location/amap.go new file mode 100644 index 00000000..a2912177 --- /dev/null +++ b/core/chat/location/amap.go @@ -0,0 +1,28 @@ +package chat + +import ( + "path" + + ice "shylinux.com/x/icebergs" + "shylinux.com/x/icebergs/base/aaa" + "shylinux.com/x/icebergs/base/mdb" + "shylinux.com/x/icebergs/base/nfs" + "shylinux.com/x/icebergs/base/web" + "shylinux.com/x/icebergs/core/chat" + kit "shylinux.com/x/toolkits" +) + +const AMAP = "amap" + +func init() { + web.Index.MergeCommands(ice.Commands{ + "/_AMapService/": {Hand: func(m *ice.Message, arg ...string) { + m.Cmdy(web.SPIDE, ice.DEV, web.SPIDE_RAW, m.R.Method, "https://restapi.amap.com/"+path.Join(arg...)+"?"+m.R.URL.RawQuery+"&jscode="+mdb.Conf(m, chat.Prefix(AMAP), kit.Keym(aaa.SECRET))).RenderResult() + }}, + }) + chat.Index.MergeCommands(ice.Commands{ + AMAP: {Name: "amap keyword auto", Help: "高德地图", Hand: func(m *ice.Message, arg ...string) { + m.Display("", nfs.SCRIPT, mdb.Config(m, nfs.SCRIPT)) + }}, + }) +} diff --git a/core/chat/location/amap.js b/core/chat/location/amap.js new file mode 100644 index 00000000..18f6cde6 --- /dev/null +++ b/core/chat/location/amap.js @@ -0,0 +1,72 @@ +Volcanos(chat.ONIMPORT, { + _init: function(can, msg, cb) { window._AMapSecurityConfig = {serviceHost: location.origin+"/_AMapService"}, can.require([can.Conf(nfs.SCRIPT)], function() { + can.require(["location.js"], function() { can.onimport._layout_init(can, msg, function() { cb && cb(msg), can.onimport._content(can) }) }) + }) }, + _content: function(can, item) { + var map = new AMap.Map(can.ui.content, {viewMode: '3D', lang: can.getHeaderLanguage().split("-")[0], zoom: can.Action("zoom"), pitch: can.Action("pitch"), rotation: can.Action("rotation")}); can.ui.map = map + can.onimport._style(can, can.getHeaderTheme()), can.onengine.listen(can, chat.ONTHEMECHANGE, function() { can.onimport._style(can, can.getHeaderTheme()) }) + map.on("moveend", function(event) { can.Action("pitch", map.getPitch().toFixed(2)), can.Action("rotation", map.getRotation()) }) + map.on("zoomend", function(event) { can.Action("zoom", map.getZoom().toFixed(2)) }) + map.on("click", function(event) { can.onexport.status(can, event.lnglat) }) + map.plugin(['AMap.ToolBar', 'AMap.Scale', 'AMap.MapType', 'AMap.Geolocation', 'AMap.Geocoder'], function() { + map.addControl(new AMap.ToolBar()), map.addControl(new AMap.Scale()), map.addControl(new AMap.MapType()) + map.addControl(can.ui.geolocation = new AMap.Geolocation({buttonPosition: 'RB', enableHighAccuracy: true})), can.ui.geocoder = new AMap.Geocoder({}) + AMap.event.addListener(can.ui.geolocation, 'complete', function() { + can.ui.map.setZoom(can.Action("zoom", 16)), can.ui.map.setPitch(can.Action("pitch", 0)), can.ui.map.setRotation(can.Action("rotation", 0)) + can.user.toastSuccess(can), can.onmotion.delay(can, function() { can.onexport.status(can) }, 500) + AMap.plugin('AMap.Weather', function() { var weather = new AMap.Weather() + weather.getLive(can.Status("city"), function(err, data) { can.Status(data) }) + }) + }) + // can.onaction.current({}, can) + can.onexport.status(can) + }) + map.add(can.ui.favor = new AMap.OverlayGroup()) + map.add(can.ui.marker = new AMap.Marker({position: [116.39, 39.9]})) + map.add(can.ui.circle = new AMap.CircleMarker({ + center: new AMap.LngLat("116.403322", "39.920255"), radius: 100, + strokeColor: "#F33", strokeWeight: 1, fillColor: "#ee2200", fillOpacity: 0.35, + })) + }, + _style: function(can, style) { + style = {"light": "normal", "dark": "grey"}[style]||style + can.ui.map.setMapStyle("amap://styles/"+can.Action("style", style)) + return style + }, + _mark: function(can, item, target) { + var p = new AMap.Marker({position: [parseFloat(item.longitude), parseFloat(item.latitude)]}) + p.on("click", function() { target.click() }), can.ui.favor.addOverlay(p) + }, +}) +Volcanos(chat.ONACTION, { + _trans: { + current: "定位", favor: "收藏", + input: { + zoom: "缩放", pitch: "倾斜", rotation: "旋转", + weather: "天气", temperature: "温度", humidity: "湿度", windPower: "风速", + }, + }, + current: function(event, can) { can.user.toastProcess(can), can.ui.geolocation.getCurrentPosition() }, + feature: function(event, can, button, value) { + if (value == "road") { + can.ui.map.setFeatures(["bg", "road"]) + } else { + can.ui.map.setFeatures(["bg", "road", "building", "point"]) + } + }, + center: function(can, item) { + can.ui.marker.setTitle(item.name) + can.ui.map.setCenter(new AMap.LngLat(parseFloat(item.longitude), parseFloat(item.latitude))) + can.onmotion.delay(can, function() { can.onexport.status(can) }, 500) + } +}) +Volcanos(chat.ONEXPORT, { + status: function(can, p) { p = p||can.ui.map.getCenter(), can.ui.marker.setPosition(p), can.ui.circle.setCenter(p) + can.Status({longitude: p.getLng().toFixed(6), latitude: p.getLat().toFixed(6)}) + can.ui.map.getCity(function(result) { can.Status(result) }) + can.ui.geocoder.getAddress(p, function(status, result) { + can.Status({text: result.regeocode.formattedAddress}) + can.Status(result.regeocode.addressComponent) + }) + }, +}) diff --git a/core/chat/location/amap.shy b/core/chat/location/amap.shy new file mode 100644 index 00000000..84280d00 --- /dev/null +++ b/core/chat/location/amap.shy @@ -0,0 +1,6 @@ +section "amap" +refer ` +高德 https://www.amap.com +文档 https://lbs.amap.com/api/javascript-api/guide/abc/prepare +后台 https://console.amap.com/dev/key/app +` diff --git a/core/chat/location/bmap.shy b/core/chat/location/bmap.shy new file mode 100644 index 00000000..5275fae5 --- /dev/null +++ b/core/chat/location/bmap.shy @@ -0,0 +1,4 @@ +section "bmap" +refer ` +https://map.baidu.com/ +` diff --git a/core/chat/location/location.go b/core/chat/location/location.go new file mode 100644 index 00000000..f4f98ee7 --- /dev/null +++ b/core/chat/location/location.go @@ -0,0 +1,48 @@ +package chat + +import ( + ice "shylinux.com/x/icebergs" + "shylinux.com/x/icebergs/base/ctx" + "shylinux.com/x/icebergs/base/mdb" + "shylinux.com/x/icebergs/base/web" + "shylinux.com/x/icebergs/base/web/html" + "shylinux.com/x/icebergs/core/chat" + kit "shylinux.com/x/toolkits" +) + +const ( + LONGITUDE = "longitude" + LATITUDE = "latitude" + PROVINCE = "province" + CITY = "city" + DISTRICT = "district" + STREET = "street" +) + +const LOCATION = "location" + +func init() { + chat.Index.MergeCommands(ice.Commands{ + LOCATION: {Help: "地图", Icon: "Maps.png", Meta: kit.Dict( + ice.CTX_TRANS, kit.Dict(html.INPUT, kit.Dict( + LONGITUDE, "经度", LATITUDE, "纬度", PROVINCE, "省份", CITY, "城市", DISTRICT, "区域", STREET, "街路", + )), + ), Actions: ice.MergeActions(ice.Actions{ + chat.FAVOR_INPUTS: {Hand: func(m *ice.Message, arg ...string) { + kit.If(arg[0] == mdb.TYPE, func() { m.Push(arg[0], LOCATION) }) + }}, + chat.FAVOR_TABLES: {Hand: func(m *ice.Message, arg ...string) { + kit.If(m.Option(mdb.TYPE) == LOCATION, func() { m.PushButton(kit.Dict(LOCATION, "地图")) }) + }}, + chat.FAVOR_ACTION: {Hand: func(m *ice.Message, arg ...string) { + kit.If(m.Option(mdb.TYPE) == LOCATION, func() { ctx.ProcessField(m, m.PrefixKey(), []string{m.Option(mdb.TEXT)}, arg...) }) + }}, + }, chat.FavorAction(), mdb.ExportHashAction(web.VENDOR, AMAP, mdb.FIELD, "time,hash,type,name,text,longitude,latitude,extra")), Hand: func(m *ice.Message, arg ...string) { + if len(arg) == 0 || arg[0] != ctx.ACTION { + mdb.HashSelect(m, kit.Slice(arg, 0, 1)...) + web.PushPodCmd(m, "", arg...) + } + m.Cmdy(mdb.Config(m, web.VENDOR), arg) + }}, + }) +} diff --git a/core/chat/location/location.js b/core/chat/location/location.js new file mode 100644 index 00000000..63877f71 --- /dev/null +++ b/core/chat/location/location.js @@ -0,0 +1,78 @@ +Volcanos(chat.ONIMPORT, {_init: function(can, msg) {}, + _layout_init: function(can, msg, cb) { + can.ui = can.onappend.layout(can); if (can.user.isMobile) { + can.page.style(can, can.ui.project, "z-index", 10, "position", "absolute") + can.page.style(can, can.ui.content, html.HEIGHT, can.ConfHeight(), html.WIDTH, can.ConfWidth()) + can.page.Select(can, can._action, "div.item.text", function(target) { can.onmotion.hidden(can, target) }) + can.onmotion.hidden(can, can._status) + } else { + can.ui.layout(can.ConfHeight(), can.ConfWidth()) + } + can.onimport._project(can), can.db.list = {} + can.user.isMobile && can.core.Item(can.ui.zone, function(key, item) { key == "favor" || item._legend.click() }) + can.user.isMobile && can.onmotion.hidden(can, can._action) + msg.Option(ice.MSG_ACTION, ""), cb && cb(msg) + if (msg.IsDetail()) { + can.onaction.center(can, can._current = can.onimport._item(can, msg.TableDetail())) + } else { + msg.Table(function(item) { can.onimport._item(can, item) }), can.ui.zone.favor._total(msg.Length()) + var item = can.db.list[can.db.hash[0]]; item? item.click(): can.user.agent.getLocation(can, function(res) { res.type = "current", can.onaction.center(can, can._current = res) }) + } + }, + _project: function(can) { can.onmotion.clear(can, can.ui.project), can.onimport.zone(can, [ + {name: "explore"}, {name: "search"}, {name: "direction"}, + {name: "favor", _menu: shy({"play": function(event, can, button) { + can.core.Next(can.page.Select(can, can.ui.zone.favor._target, html.DIV_ITEM), function(item, next) { + item.click(), can.onmotion.delay(can, next, 3000) + }, function() { can.user.toastSuccess(can) }) + }})}, + {name: "district", _delay_init: function(target, zone) { can.onimport._province(can, target) }}, + ], can.ui.project) }, + _item: function(can, item, target) { if (!item.latitude || !item.longitude) { return item } + var _target = can.onimport.item(can, item, function(event) { + can.onaction.center(can, item), can.ui.map.setZoom(can.Action("zoom", 16)), can.misc.SearchHash(can, item.hash) + can.onimport.plugin(can, item) && can.onmotion.delay(can, function() { var ls = can.ui.map.getBounds().path + can.ui.map.setCenter([ls[1][0]-(ls[1][0]-ls[3][0])*3/8, ls[1][1]+(ls[3][1]-ls[1][1])*3/8]) + }, 500) + }, function(event) { + can.onaction.center(can, item), can.user.carteRight(event, can, { + plugin: function(event, button) { can.user.input(can.request(event, item), can, [ctx.INDEX, ctx.ARGS], function(data) { + item.extra = can.base.Copy(item.extra||{}, data), can.onimport.plugin(can, item) + can.runAction(event, mdb.MODIFY, ["extra.index", data.index, "extra.args", data.args], function() {}) + }) }, + favor: function(event) { can.request(event, item), can.onaction.create(event, can) }, + direction: function(event, button) { can.onaction.center(can, item), can.onaction[button](event, can, button) }, + remove: function(event, button) { can.runAction(event, mdb.REMOVE, [mdb.HASH, item.hash], function() { can.page.Remove(can, _target) }) }, + }) + }, target||can.ui.zone.favor._target); can.db.list[item.hash] = _target, can.ui.zone.favor._total() + return can.onimport._mark(can, item, _target), item + }, + _mark: function(can, item) {}, + _style: function(can, style) {}, + plugin: function(can, item) { var extra = can.base.Obj(item.extra, {}); can.onmotion.toggle(can, can.ui.profile, true) + if (can.onmotion.cache(can, function() { return item.hash }, can.ui.profile)) { return true } + if (!extra.index) { return can.onmotion.toggle(can, can.ui.profile, false) } + can.onappend.plugin(can, {space: item.space, index: extra.index, args: extra.args}, function(sub) { item._plugin = sub + sub.onaction._close = function() { can.onmotion.hidden(can, can.ui.profile) } + sub.onexport.output = function() { sub.onimport.size(sub, can.ConfHeight()/2, can.ConfWidth()/2, true) + can.page.style(can, can.ui.profile, html.HEIGHT, can.ConfHeight()/2, html.WIDTH, can.ConfWidth()/2) + } + }, can.ui.profile) + return true + }, +}) +Volcanos(chat.ONACTION, { + list: [ + ["style", "normal", "light", "whitesmoke", "fresh", "macaron", "graffiti", "darkblue", "blue", "grey", "dark"], + ["feature", "point", "road"], + {type: html.TEXT, name: "zoom", value: 16, range: [3, 21]}, + {type: html.TEXT, name: "pitch", value: 30, range: [0, 80, 5]}, + {type: html.TEXT, name: "rotation", value: 0, range: [0, 360, 10]}, + "current:button", "explore", "search", "direction", mdb.CREATE, + ], _trans: {current: "定位", favor: "收藏"}, + style: function(event, can, button, value) { can.onimport._style(can, value) }, + zoom: function(event, can) { can.ui.map.setZoom(can.Action("zoom")) }, + pitch: function(event, can) { can.ui.map.setPitch(can.Action("pitch")) }, + rotation: function(event, can) { can.ui.map.setRotation(can.Action("rotation")) }, +}) +Volcanos(chat.ONEXPORT, {list: ["province", "city", "district", "street", "longitude", "latitude", "type", "name", "text", "space", "weather", "temperature", "humidity", "windPower"]}) diff --git a/core/chat/location/location.shy b/core/chat/location/location.shy new file mode 100644 index 00000000..ccc40743 --- /dev/null +++ b/core/chat/location/location.shy @@ -0,0 +1,4 @@ +chapter "地图" +source bmap.shy +source amap.shy +source tmap.shy diff --git a/core/chat/location.go b/core/chat/location/tmap.go similarity index 50% rename from core/chat/location.go rename to core/chat/location/tmap.go index b68328d8..c86138df 100644 --- a/core/chat/location.go +++ b/core/chat/location/tmap.go @@ -4,33 +4,29 @@ import ( "net/http" ice "shylinux.com/x/icebergs" - "shylinux.com/x/icebergs/base/ctx" + "shylinux.com/x/icebergs/base/aaa" "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/nfs" "shylinux.com/x/icebergs/base/web" + "shylinux.com/x/icebergs/core/chat" kit "shylinux.com/x/toolkits" ) -const ( - LATITUDE = "latitude" - LONGITUDE = "longitude" -) - -const LOCATION = "location" +const TMAP = "tmap" func init() { get := func(m *ice.Message, api string, arg ...ice.Any) string { return kit.Format(mdb.Cache(m, kit.Join(kit.Simple(api, arg)), func() ice.Any { - res := kit.UnMarshal(m.Cmdx(web.SPIDE, LOCATION, web.SPIDE_RAW, http.MethodGet, api, mdb.KEY, mdb.Config(m, web.TOKEN), arg)) + res := kit.UnMarshal(m.Cmdx(web.SPIDE, TMAP, web.SPIDE_RAW, http.MethodGet, api, mdb.KEY, mdb.Config(m, aaa.SECRET), arg)) m.Warn(kit.Format(kit.Value(res, mdb.STATUS)) != "0", kit.Format(res)) m.Debug("what %v %v", api, kit.Formats(res)) return res })) } - Index.MergeCommands(ice.Commands{ - LOCATION: {Help: "地图", Icon: "Maps.png", Actions: ice.MergeActions(ice.Actions{ + chat.Index.MergeCommands(ice.Commands{ + TMAP: {Actions: ice.Actions{ ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { - m.Cmd(web.SPIDE, mdb.CREATE, LOCATION, "https://apis.map.qq.com/ws/") + m.Cmd(web.SPIDE, mdb.CREATE, TMAP, "https://apis.map.qq.com/ws/") }}, "explore": {Help: "周边", Hand: func(m *ice.Message, arg ...string) { m.Echo(get(m, "place/v1/explore", m.OptionSimple("keyword,boundary,page_index"))) @@ -44,22 +40,10 @@ func init() { "district": {Help: "地区", Hand: func(m *ice.Message, arg ...string) { m.Echo(get(m, "district/v1/getchildren", m.OptionSimple(mdb.ID))) }}, - FAVOR_INPUTS: {Hand: func(m *ice.Message, arg ...string) { - kit.If(arg[0] == mdb.TYPE, func() { m.Push(arg[0], LOCATION) }) - }}, - FAVOR_TABLES: {Hand: func(m *ice.Message, arg ...string) { - kit.If(m.Option(mdb.TYPE) == LOCATION, func() { m.PushButton(kit.Dict(LOCATION, "地图")) }) - }}, - FAVOR_ACTION: {Hand: func(m *ice.Message, arg ...string) { - kit.If(m.Option(mdb.TYPE) == LOCATION, func() { ctx.ProcessField(m, m.PrefixKey(), []string{m.Option(mdb.TEXT)}, arg...) }) - }}, - }, FavorAction(), mdb.ExportHashAction(mdb.FIELD, "time,hash,type,name,text,latitude,longitude,extra", nfs.SCRIPT, "https://map.qq.com/api/gljs?v=1.exp")), Hand: func(m *ice.Message, arg ...string) { - mdb.HashSelect(m, kit.Slice(arg, 0, 1)...) + }, Hand: func(m *ice.Message, arg ...string) { // m.Option(LOCATION, m.Cmdx(web.SERVE, tcp.HOST)) // m.Option(LOCATION, get(m, "location/v1/ip", aaa.IP, m.Option(ice.MSG_USERIP))) - web.PushPodCmd(m, "", arg...) - ctx.DisplayLocal(m.Options(nfs.SCRIPT, kit.MergeURL(mdb.Config(m, nfs.SCRIPT), mdb.KEY, mdb.Config(m, web.TOKEN))), "") - ctx.Toolkit(m, "") + m.Display("", nfs.SCRIPT, mdb.Config(m, nfs.SCRIPT)) }}, }) } diff --git a/core/chat/location/tmap.js b/core/chat/location/tmap.js new file mode 100644 index 00000000..e3cff8c9 --- /dev/null +++ b/core/chat/location/tmap.js @@ -0,0 +1,209 @@ +Volcanos(chat.ONIMPORT, {_init: function(can, msg, cb) { can.require([msg.Option(nfs.SCRIPT)], function() { + can.require(["location.js"], function() { can.onimport._layout_init(can, msg, function() { cb && cb(msg) + var res = {type: "unknown", latitude: 39.984120, longitude: 116.307480}, current = can.base.Obj(msg.Option(chat.LOCATION), {}) + res.nation = current.nation||current.country, res.province = current.province||current.regionName, res.city = current.city + res.latitude = current.latitude||current.lat||res.latitude, res.longitude = current.longitude||current.lon||res.longitude + res.name = current.name||"当前位置", res.text = current.text||"某某大街", res.ip = current.ip||current.query + can.onimport._content(can, can._current = res), can.Status(can._current = res) + }) }) + }) }, + _mark: function(can, item) { + can.mark && can.mark.add({position: can.onimport.point(can, item), properties: item}) + }, + _explore: function(can, keyword, i) { var p = can.onimport.point(can, can.current.item) + can.runAction(can.request({}, {_method: http.GET, "boundary": "nearby("+can.base.join([p.lat, p.lng, "500"], mdb.FS)+")", "page_index": i||1, "keyword": keyword}), "search", [], function(msg) { + var res = can.base.Obj(msg.Result()); can.core.List(res.data, function(item) { + can.onimport._item(can, can.onexport.point(can, item.location, {type: item.category, name: item.title, text: item.address}), can.ui.zone.explore._target) + }) + }) + }, + _search: function(can, keyword, i) { var p = can.onimport.point(can, can.current.item) + can.runAction(can.request({}, {_method: http.GET, "boundary": "region("+can.base.join([can.Status("city"), p.lat, p.lng], mdb.FS)+")", "page_index": i||1, "keyword": keyword}), "search", [], function(msg) { + var res = can.base.Obj(msg.Result()); can.core.List(res.data, function(item) { + can.onimport._item(can, can.onexport.point(can, item.location, {type: item.category, name: item.title, text: item.address}), can.ui.zone.search._target) + }) + }) + }, + _list_result: function(can, msg, cb) { var res = can.base.Obj(msg.Result()); if (res.status) { can.user.toastFailure(can, res.message); return } + return res && res.result && can.core.List(res.result[0], function(item) { item.name = item.name||item.fullname; return can.base.isFunc(cb)? cb(item): item }) + }, + _district: function(can, id, cb) { can.runAction(can.request({}, {_method: http.GET, id: id}), "district", [], cb) }, + _province: function(can, target) { can.onimport._district(can, "", function(msg) { + can.onimport._list_result(can, msg, function(province) { + can.onimport.item(can, province, function(event, _, show) { if (show === false) { return } + can.onaction.center(can, can.onexport.point(can, province.location, {type: "province", name: province.name, text: province.fullname})) + can.map.setZoom(can.Action("zoom", 8)), can.Status({nation: "中国", province: province.fullname}) + show === true || can.onimport._city(can, province, event.target) + }, function() {}, target) + }) + }) }, + _city: function(can, province, target) { can.onimport._district(can, province.id, function(msg) { + can.onimport.itemlist(can, can.onimport._list_result(can, msg), function(event, city, show) { if (show === false) { return } + can.onaction.center(can, can.onexport.point(can, city.location, {type: "city", name: city.name, text: city.fullname})) + can.map.setZoom(can.Action("zoom", 12)), can.Status({nation: "中国", province: province.fullname, city: city.fullname}) + show === true || can.onimport._county(can, province, city, event.target) + }, function() {}, target) + }) }, + _county: function(can, province, city, target) { can.onimport._district(can, city.id, function(msg) { + can.onimport.itemlist(can, can.onimport._list_result(can, msg), function(event, county) { + can.onaction.center(can, can.onexport.point(can, county.location, {type: "county", name: city.name, text: county.fullname})) + can.map.setZoom(can.Action("zoom", 15)), can.Status({nation: "中国", province: province.fullname, city: city.fullname}) + }, function() {}, target) + }) }, + _content: function(can, item) { + can.map = new TMap.Map(can.ui.content, { + center: can.onimport.point(can, item), + zoom: can.Action("zoom"), pitch: can.Action("pitch"), rotation: can.Action("rotation"), + }) + can.map.on("zoom", function(event) { can.Action("zoom", can.map.getZoom().toFixed(2)) }) + can.map.on("pitch", function(event) { can.Action("pitch", can.map.getPitch().toFixed(2)) }) + can.map.on("rotate", function(event) { can.Action("rotation", can.map.getRotation().toFixed(2)) }) + can.map.on("click", function(event) { var point = can.onaction._point(event, can, {name: event.poi? event.poi.name: ""}); can.onaction.center(can, point) }) + can.ui.map = can.map + can.current = {item: item, info: can.onfigure.info(can, item), hover: can.onfigure.info(can, item), + label: new TMap.MultiLabel({map: can.map, geometries: [{id: "current", position: can.onimport.point(can, item), content: item.name}]}), + marker: new TMap.MultiMarker({map: can.map, geometries: [{id: "current", position: can.onimport.point(can, item)}]}), + circle: can.onfigure.circle(can, item, 100), + } + can.onfigure._mark(can), can.mark && can.mark.add({position: can.onimport.point(can, can._current), properties: can._current}) + can.page.Select(can, can._target, "div.content>div", function(item) { can.page.style(can, item, {"z-index": 9}) }) + }, + point: function(can, item) { return new TMap.LatLng(item.latitude, item.longitude) }, + _plugin: function(can, item, meta) { + function myInfoWindow(options) { TMap.DOMOverlay.call(this, options) } + myInfoWindow.prototype = new TMap.DOMOverlay() + myInfoWindow.prototype.onInit = function(options) { this.position = options.position, this.meta = options.meta } + myInfoWindow.prototype.createDOM = function() { + var meta = this.meta, ui = can.onappend.field(can, chat.FLOAT, {}, can._output) + can.onappend.plugin(can, meta, function(sub) { + sub.run = function(event, cmds, cb) { can.runAction(can.request(event), ctx.RUN, [meta.index].concat(cmds), cb) } + sub.onaction.close = function(event) { can.misc.Event(event, can, function(msg) { + can.onmotion.hidden(can, sub._target) + }) } + item._plugin = sub + }, can._output, ui.fieldset) + return ui.fieldset + } + myInfoWindow.prototype.updateDOM = function() { + var pixel = this.map.projectToContainer(this.position); can.page.style(can, this.dom, { + left: pixel.getX(), top: pixel.getY()+2*html.ACTION_HEIGHT, + }) + } + return new myInfoWindow({map: can.map, position: can.onimport.point(can, item), meta: meta}) + }, +}, ["location.js"]) +Volcanos(chat.ONFIGURE, { + circle: function(can, item, radius) { + return new TMap.MultiCircle({ + map: can.map, styles: {circle: new TMap.CircleStyle({color: 'rgba(41,91,255,0.16)', borderColor: 'rgba(41,91,255,1)', borderWidth: 2, showBorder: true})}, + geometries: [{styleId: 'circle', center: can.onimport.point(can, item), radius: radius||300}], + }) + }, + info: function(can, item) { + return new TMap.InfoWindow({map: can.map, + position: can.onimport.point(can, item), offset: {x: 0, y: -32}, + content: (item.name||"")+"
"+(item.text||""), + }) + }, + _mark: function(can, msg) { can.mark = new TMap.MultiMarker({map: can.map}) + can.mark.on("click", function(event) { if (!event.geometry) { return } + var item = event.geometry.properties; can.db.list[item.hash].click() + }) + can.mark.on("hover", function(event) { if (!event.geometry) { return } + var item = event.geometry.properties; can.onexport.hover(can, item) + }) + }, + _polyline: function(can, path) { return new TMap.MultiPolyline({ + map: can.map, styles: { + 'style_blue': new TMap.PolylineStyle({ + 'color': '#3777FF', //线填充色 + 'width': 6, //折线宽度 + 'borderWidth': 5, //边线宽度 + 'borderColor': '#FFF', //边线颜色 + 'lineCap': 'butt' //线端头方式 + }), + 'style_red': new TMap.PolylineStyle({ + 'color': '#CC0000', //线填充色 + 'width': 6, //折线宽度 + 'borderWidth': 5, //边线宽度 + 'borderColor': '#CCC', //边线颜色 + 'lineCap': 'round' //线端头方式 + }) + }, geometries: [{'styleId': 'style_blue', 'paths': path}] + }) }, + _move: function(can) { + can.mark.add({id: 'car', styleId: 'car-down', position: new TMap.LatLng(39.98481500648338, 116.30571126937866)}) + can.mark.moveAlong({"car": {path: [ + new TMap.LatLng(39.98481500648338, 116.30571126937866), + new TMap.LatLng(39.982266575222155, 116.30596876144409), + new TMap.LatLng(39.982348784165886, 116.3111400604248), + new TMap.LatLng(39.978813710266024, 116.3111400604248), + new TMap.LatLng(39.978813710266024, 116.31699800491333) + ], speed: 70}}, {autoRotation:true}) + }, +}) +Volcanos(chat.ONACTION, { + _point: function(event, can, item) { var rect = can.ui.content.getBoundingClientRect() + return can.base.Copy({left: rect.left+event.point.x, bottom: rect.top+event.point.y, latitude: event.latLng.lat.toFixed(6), longitude: event.latLng.lng.toFixed(6)}, item, true) + }, + center: function(can, item) { + var point = can.onimport.point(can, item); can.map.setCenter(point); if (!item.name) { return } + can.current.item = item, can.Status(mdb.NAME, ""), can.Status(mdb.TEXT, ""), can.Status(item), can.Status({latitude: point.lat, longitude: point.lng}) + can.current.info.setPosition(point), can.current.info.setContent((item.name||"")+"
"+(item.text||"")) + can.current.label.updateGeometries([{id: "current", position: point, content: item.name}]) + can.current.marker.updateGeometries([{id: "current", position: point}]) + can.current.circle.setGeometries([{center: point, radius: 300}]) + can.onimport.plugin(can, item) + }, + current: function(event, can) { can.onaction.center(can, can._current), can.map.setZoom(can.Action("zoom", 16)), can.map.setPitch(can.Action("pitch", 30)), can.map.setRotation(can.Action("rotation", 0)) }, + explore: function(event, can, button) { can.onmotion.clear(can, can.ui.zone.explore._target) + can.user.input(event, can, ["keyword"], function(list) { + for (var i = 1; i < 6; i++) { + can.onimport._explore(can, list[0], i) + } + }) + }, + search: function(event, can, button) { can.onmotion.clear(can, can.ui.zone.search._target) + can.user.input(event, can, ["keyword"], function(list) { + for (var i = 1; i < 6; i++) { + can.onimport._search(can, list[0], i) + } + }) + }, + direction: function(event, can, button) { var p = can.map.getCenter(); can.onmotion.clear(can, can.ui.zone.direction._target) + can.user.input(event, can, [["type", "driving", "walking", "bicycling", "transit"]], function(list) { + var from = can.onimport.point(can, can._current), to = can.onimport.point(can, can.current.item) + var msg = can.request({}, {_method: http.GET, type: list[0], "from": can.base.join([from.lat, from.lng], mdb.FS), "to": can.base.join([to.lat, to.lng], mdb.FS)}) + can.runAction(msg._event, button, [], function(msg) { var res = can.base.Obj(msg.Result()), route = res.result.routes[0] + var coors = route.polyline, pl = [], kr = 1000000 + for (var i = 2; i < coors.length; i++) { coors[i] = Number(coors[i - 2]) + Number(coors[i]) / kr } + for (var i = 0; i < coors.length; i += 2) { pl.push(new TMap.LatLng(coors[i], coors[i+1])) } + can.onfigure._polyline(can, pl) + can.core.List(route.steps, function(item) { var i = item.polyline_idx[0] + can.onimport._item(can, can.onexport.point(can, {lat: coors[i], lng: coors[i+1]}, {type: item.category, name: item.instruction, text: item.act_desc}), can.ui.zone.direction._target) + }), can.user.toastProcess(can, "distance: "+route.distance+" duration: "+route.duration) + }) + }) + }, + create: function(event, can) { can.request(event, can.current.item) + can.user.input(event, can, can.core.Split("type,name,text"), function(args) { var p = can.onexport.center(can) + can.runAction(event, mdb.CREATE, args.concat("latitude", p.latitude, "longitude", p.longitude), function(msg) { + can.onimport._item(can, can.base.Copy(p, {name: msg.Option(mdb.NAME), text: msg.Option(mdb.TEXT)})) + }, true) + }) + }, +}) +Volcanos(chat.ONEXPORT, { + point: function(can, point, item) { return can.base.Copy({latitude: point.lat, longitude: point.lng}, item, true) }, + center: function(can) { return can.onexport.point(can, can.map.getCenter()) }, + current: function(can) { + var p = can.onexport.center(can); p.latitude, p.longitude; can.Status(p) + can.current.marker.updateGeometries([{id: "current", position: can.map.getCenter()}]) + can.current.label.updateGeometries([{id: "current", position: can.map.getCenter()}]) + can.current.circle.setGeometries([{center: can.map.getCenter(), radius: 300}]) + }, + hover: function(can, item) { + can.current.hover.setPosition(can.onimport.point(can, item)) + can.current.hover.setContent(item.name+"
"+item.text) + }, +}) diff --git a/core/chat/location.shy b/core/chat/location/tmap.shy similarity index 93% rename from core/chat/location.shy rename to core/chat/location/tmap.shy index 7902be78..f49169b5 100644 --- a/core/chat/location.shy +++ b/core/chat/location/tmap.shy @@ -1,8 +1,7 @@ -section "location" +section "tmap" refer ` 后台 https://lbs.qq.com/dev/console/application/mine 后端 https://lbs.qq.com/service/webService/webServiceGuide/webServiceOverview 前端 https://lbs.qq.com/webApi/javascriptGL/glGuide/glBasic 手册 https://lbs.qq.com/webApi/javascriptGL/glDoc/docIndexMap ` - diff --git a/core/core.go b/core/core.go index 4ae40d7b..cfc44a80 100644 --- a/core/core.go +++ b/core/core.go @@ -2,6 +2,7 @@ package core import ( _ "shylinux.com/x/icebergs/core/chat" + _ "shylinux.com/x/icebergs/core/chat/location" _ "shylinux.com/x/icebergs/core/chat/macos" _ "shylinux.com/x/icebergs/core/code" _ "shylinux.com/x/icebergs/core/mall" diff --git a/info.go b/info.go index 564fe3c0..577119f2 100644 --- a/info.go +++ b/info.go @@ -217,7 +217,7 @@ func SplitCmd(name string, actions Actions) (list []Any) { push(BUTTON, "next") push(TEXT, "offend") push(TEXT, "limit") - case ARGS, CONTENT, TEXTAREA, TEXT: + case ARGS, CONTENT, TEXTAREA, TEXT, "extra": push(TEXTAREA, ls[i]) case PASSWORD: push(PASSWORD, ls[i])