20、社交地图项目:高级交互标记与多推文集成

社交地图:交互标记与多推文集成

社交地图项目:高级交互标记与多推文集成

在社交地图项目中,我们的目标是为 Twitter 搜索结果增添更多细节,打造一个功能丰富且交互性强的地图应用。以下将详细介绍如何逐步实现这些功能。

构建高级交互标记

在社交地图项目里,我们期望在 Twitter 搜索结果出现时自动打开信息面板。为达成这一目标,我们将创建 Google Marker 的子类并进行扩展,同时添加新的 InfoWindow,以便将实时 HTML 数据直接添加到地图中。

操作步骤
  1. 替换标记 :在 showTweet 函数中,用 TwitterMarker 标记替换原有的新标记。
function showTweet(obj,latLng){
    if(!obj) obj = {text:'No tweet found in this area for this topic'};
    console.log(obj);   
    var marker = new TwitterMarker({
        map: map,
        position: latLng,
        tweet: obj,
        title:obj.text    
    });     
}
  1. 创建自定义标记 :创建 TwitterMarker 构造函数。
function TwitterMarker(opt){
    var strTweet = this.buildTwitterHTML(opt.tweet);
    this.infoWindow = new google.maps.InfoWindow({
        maxWidth:300,
        content:strTweet
    });
    this.setValues(opt);
    this.infoWindow.open(this.map,this);
    google.maps.event.addListener(this, 'click', this.onMarkerClick);
}
  1. 继承标记功能 :将 TwitterMarker google.maps.Marker 扩展,使其具备常规标记的所有特性。
TwitterMarker.prototype = new google.maps.Marker();
  1. 创建切换按钮 :在标记事件监听器中创建切换按钮,用于打开或关闭 InfoWindow。
TwitterMarker.prototype.onMarkerClick=function(evt){
    this.isOpen=!this.isOpen;
    if(this.isOpen)
        this.infoWindow.close();
    else
        this.infoWindow.open(this.map,this);
}
  1. 创建 Twitter 消息 HTML 字符串 :实现 buildTwitterHTML 方法,根据 Twitter 对象构建 HTML 字符串。
TwitterMarker.prototype.buildTwitterHTML = function(twt){
    var str;
    if(twt.from_user_name){
        str =   
        "<span><img style='float: left' src='"+twt.profile_image_url+"' />"+
            "<b>" +twt.from_user_name + "</b><br/><a href ='http://twitter.com/"
            + twt.from_user + "'>@"+twt.from_user+"</a><br/> "
            + twt.location + "</span>"
            + "<p>"+twt.text+"</p>";
    }else{
        str="The 50 Kilometer radius around this point did not message this value";
    }
    return str;
}
工作原理

这里运用了 JavaScript 的继承机制,通过定义原型来扩展对象的功能。 buildTwitterHTML 方法将 Twitter 对象的数据转换为 HTML,每个标记对应一个 InfoWindow,用于展示推文信息。切换按钮的逻辑基于 isOpen 变量的状态切换,通过点击标记改变其值,从而实现 InfoWindow 的打开和关闭。

添加多条推文到 InfoWindow 气泡

为了在 InfoWindow 中显示多条推文,我们将添加分页系统。

操作步骤
  1. 更改搜索结果数量 :将 Twitter 搜索结果数量设置为每次最多返回 100 条。
var searchLink = 'http://search.twitter.com/search.json?q='+ searchKeyWord+ '&geocode=' + geocode +"&result_type=recent&rpp=100";
  1. 更新引用 :修改代码引用,将完整的推文数组传递给 TwitterMarker 标记。
google.maps.event.addListener(map, 'click', function(e) {
    var searchKeyWord = 'html5';
    var geocode=e.latLng.lat() + "," + e.latLng.lng()+",50km";
    var searchLink = 'http://search.twitter.com/search.json?q='+ searchKeyWord+ '&geocode=' + geocode +"&result_type=recent&rpp=100";
    $.getJSON(searchLink, function(data) {
        showTweet(data.results,e.latLng);
    });
});
function showTweet(a,latLng){
    if(!a) a = [{text:'No tweet found in this area for this topic'}];
    var marker = new TwitterMarker({
        map: map,
        position: latLng,
        tweet: a,
        title:a[0].text    
    }); 
}
  1. 更新构造函数 :在 TwitterMarker 构造函数中添加数组信息和标识符。
function TwitterMarker(opt){
    this.count = opt.tweet.length;
    this.crnt = 0;
    this.id = TwitterMarker.aMarkers.push(this);
    this.aTweets = opt.tweet;
    var strTweet = this.buildTwitterHTML(opt.tweet[0])
    this.infoWindow = new google.maps.InfoWindow({
        maxWidth:300,
        content:strTweet
    });
    this.setValues(opt);
    this.infoWindow.open(this.map,this);
    google.maps.event.addListener(this, 'click', this.onMarkerClick);
}
  1. 存储标记 :添加静态数组 TwitterMarker.aMarkers 来存储所有创建的标记。
TwitterMarker.prototype = new google.maps.Marker();
TwitterMarker.aMarkers= [];
  1. 添加前后链接 :在 buildTwitterHTML 方法中添加前后链接,以便用户在 InfoWindow 中切换推文。
TwitterMarker.prototype.buildTwitterHTML = function(twt){
    var str;
    if(twt.from_user_name){
        str =   
        "<span><img style='float: left' src='"+twt.profile_image_url+"' />"+
            "<b>" +twt.from_user_name + "</b><br/><a href ='http://twitter.com/"
            + twt.from_user + "'>@"+twt.from_user+"</a><br/> "
            + twt.location + "</span>"
            + "<p>"+twt.text+"</p>";
        if(this.count>1){
            str+="<span style='absolute; bottom: 0; right: 0px; width:80px'>";
            if(this.crnt!=0) str+="<a href='javascript:TwitterMarker.aMarkers["+(this.id-1)+"].prev();'>&lt;</a> ";
            str+= (this.crnt+1) + " of " + this.count;
            if(this.crnt<(this.count-1)) str+= "<a href='javascript:TwitterMarker.aMarkers["+(this.id-1)+"].next();'>&gt;</a> ";
            str+= "</span>" 
        }
    }else{
        str="The 50 Kilometer radius around this point did not message this value";
    }
    return str;
}
  1. 添加前后方法 :实现 next prev 方法,用于切换推文。
TwitterMarker.prototype.next =function(){
    this.infoWindow.close();
    this.infoWindow.content = this.buildTwitterHTML(this.aTweets[++this.crnt]);
    this.infoWindow.open(this.map,this);
    return false;   
}
TwitterMarker.prototype.prev =function(){
    this.infoWindow.close();
    this.infoWindow.content = this.buildTwitterHTML(this.aTweets[--this.crnt]);
    this.infoWindow.open(this.map,this);
    return false;   
}
工作原理

首先改变 Twitter 搜索 API 返回的结果数量,这促使代码引用从直接引用第一个返回对象转变为关注完整结果对象并传递给 TwitterMarker 构造函数。通过静态数组 TwitterMarker.aMarkers 存储所有标记,利用标记的唯一标识符在 HTML 中添加前后链接,点击链接时触发相应的 next prev 方法,实现推文的切换。

以下是添加多条推文到 InfoWindow 气泡的流程图:

graph LR
    A[更改搜索结果数量] --> B[更新引用]
    B --> C[更新构造函数]
    C --> D[存储标记]
    D --> E[添加前后链接]
    E --> F[添加前后方法]
自定义标记外观

为了让标记更具特色,我们将更新标记的外观,使其看起来像 Twitter 鸟,并添加一个图形层来为 Twitter 标记添加阴影,阴影的不透明度根据推文数量而定。

操作步骤
  1. 更新 showTweet 函数 :在 showTweet 函数中指定标记的图标。
function showTweet(a,latLng){
    if(!a) a = [{text:'No tweet found in this area for this topic'}];
    var marker = new TwitterMarker({
        map: map,
        position: latLng,
        tweet: a,
        title:a[0].text,
        icon:"img/bird.png"    
    }); 
}
  1. 创建 MarkerCounter 实例 :在 TwitterMarker 构造函数中创建 MarkerCounter 对象。
function TwitterMarker(opt){
    this.count = opt.tweet.length;
    this.mc = new MarkerCounter(opt);
    this.crnt = 0;
    // 其他代码...
}
  1. 创建 MarkerCounter 构造函数
function MarkerCounter(opt) {
    this.radius = 15;
    this.opacity = (opt.tweet.length) /100;
    this.opt = opt;
    this.setMap(opt.map);
}
  1. 创建子类 :将 MarkerCounter 作为 google.maps.OverlayView 的子类。
MarkerCounter.prototype = new google.maps.OverlayView();
  1. 实现 onAdd 方法 :在元素添加到地图时自动调用,完成绘制的准备工作。
MarkerCounter.prototype.onAdd = function() {
    var div = document.createElement('div');
    div.style.border = "none";
    div.style.borderWidth = "0px";
    div.style.position = "absolute";
    this.canvas = document.createElement("CANVAS");
    this.canvas.width = this.radius*2;
    this.canvas.height = this.radius*2;
    this.context = this.canvas.getContext("2d");
    div.appendChild(this.canvas);
    this.div_ = div;
    var panes = this.getPanes();
    panes.overlayLayer.appendChild(div);
}
  1. 重写 draw 方法 :绘制图形并定位元素。
MarkerCounter.prototype.draw = function() {
    var radius = this.radius;
    var context = this.context;
    context.clearRect(0,0,radius*2,radius*2);
    context.fillStyle = "rgba(73,154,219,"+this.opacity+")";
    context.beginPath();
    context.arc(radius,radius, radius, 0, Math.PI*2, true);
    context.closePath();
    context.fill();
    var projection = this.getProjection();
    var point = projection.fromLatLngToDivPixel(this.opt.position);
    this.div_.style.left = (point.x - radius) + 'px';
    this.div_.style.top = (point.y - radius) + 'px';
};
工作原理

通过传递 icon 参数来替换标记的默认图形。创建 MarkerCounter 作为 google.maps.OverlayView 的子类,利用 onAdd 方法完成绘制的准备工作, draw 方法进行图形绘制和元素定位。根据推文数量计算阴影的不透明度,实现不同的视觉效果。

以下是自定义标记外观的操作步骤表格:
| 步骤 | 操作 |
| ---- | ---- |
| 1 | 更新 showTweet 函数指定图标 |
| 2 | 创建 MarkerCounter 实例 |
| 3 | 创建 MarkerCounter 构造函数 |
| 4 | 创建子类 |
| 5 | 实现 onAdd 方法 |
| 6 | 重写 draw 方法 |

通过以上步骤,我们逐步实现了社交地图项目的各项功能,使其更加丰富和交互性强。后续还可以进一步优化,如更方便地更改搜索词、比较两个搜索结果等。

社交地图项目:高级交互标记与多推文集成

处理无结果情况

在实际应用中,有时可能在特定区域没有搜索到推文。为了更好地处理这种情况,我们需要对代码进行一些调整。

操作步骤
  1. 更新 showTweet 函数 :移除原有的错误逻辑,仅更新文本属性,不创建新数组。
function showTweet(a,latLng){
    var marker = new TwitterMarker({
        map: map,
        position: latLng,
        tweet: a,
        title:a.length? a[0].text : 'No tweet found in this area for this topic',
        icon:"img/bird.png"    
    }); 
}

这里使用了三元运算符 condition? true outcome: false outcome; 来简洁地判断是否有推文,并设置相应的标题。

  1. 修改 TwitterMarker 构造函数 :在构造函数中检查是否有推文,如果没有则更新图标为替代图标。
function TwitterMarker(opt){
    if(!opt.tweet || !opt.tweet.length){
        opt.icon = "img/x.png"; 
    }else{
        this.count = opt.tweet.length;
        this.mc = new MarkerCounter(opt);
        this.crnt = 0;
        this.id = TwitterMarker.aMarkers.push(this);
        this.aTweets = opt.tweet;
        var strTweet = this.buildTwitterHTML(opt.tweet[0])
        this.infoWindow = new google.maps.InfoWindow({
            maxWidth:300,
            content:strTweet
        });
        this.infoWindow.open(this.map,this);
        google.maps.event.addListener(this, 'click', this.onMarkerClick);
    }
    this.setValues(opt);
}

通过这种方式,当没有推文时,标记会显示替代图标,避免创建无效的可视化内容。

工作原理

showTweet 函数中,使用三元运算符根据推文数组的长度设置标题。在 TwitterMarker 构造函数中,首先检查是否有推文,如果没有则更新图标,否则正常处理推文信息。最后调用 setValues(opt) 确保标记正确渲染。

以下是处理无结果情况的操作步骤列表:
1. 更新 showTweet 函数,使用三元运算符设置标题。
2. 修改 TwitterMarker 构造函数,检查推文数量并更新图标。

总结与展望

通过一系列的操作,我们成功实现了社交地图项目的多个功能,包括构建高级交互标记、添加多条推文到 InfoWindow 气泡以及自定义标记外观,并处理了无结果的情况。以下是整个项目的主要操作步骤总结表格:
| 功能模块 | 操作步骤 |
| ---- | ---- |
| 构建高级交互标记 | 1. 替换标记
2. 创建自定义标记
3. 继承标记功能
4. 创建切换按钮
5. 创建 Twitter 消息 HTML 字符串 |
| 添加多条推文到 InfoWindow 气泡 | 1. 更改搜索结果数量
2. 更新引用
3. 更新构造函数
4. 存储标记
5. 添加前后链接
6. 添加前后方法 |
| 自定义标记外观 | 1. 更新 showTweet 函数
2. 创建 MarkerCounter 实例
3. 创建 MarkerCounter 构造函数
4. 创建子类
5. 实现 onAdd 方法
6. 重写 draw 方法 |
| 处理无结果情况 | 1. 更新 showTweet 函数
2. 修改 TwitterMarker 构造函数 |

整个项目的流程图如下:

graph LR
    A[构建高级交互标记] --> B[添加多条推文到 InfoWindow 气泡]
    B --> C[自定义标记外观]
    C --> D[处理无结果情况]

虽然我们已经完成了社交地图项目的基本功能,但仍有许多可以改进和扩展的地方。例如,可以实现更方便的搜索词更改功能,让用户能够轻松切换搜索主题;还可以比较两个不同搜索结果,为用户提供更多有价值的信息。这些扩展功能将进一步提升社交地图的实用性和趣味性,为用户带来更好的体验。

通过不断优化和扩展,社交地图项目将能够满足更多用户的需求,在社交数据可视化领域发挥更大的作用。希望以上内容能为你在开发类似项目时提供一些有用的参考和思路。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值