MapBox Android版开发 3 地图样式v11

前言

可以使用Mapbox Maps SDK自定义数据样式、调整地图样式、添加字体、创建数据驱动的可视化等。可以使用Mapbox StandardMapbox Standard Satellite,或通过调整地图的颜色、图标和字体来创建自定义地图样式。

有两种方法可以自定义地图的外观:

  • 使用Mapbox Studio创建自定义地图样式。
  • 使用Maps SDK在运行时动态更新地图功能。并可以动态切换语言,调整标签大小以提高可读性,根据一天中的时间调暗地图,个性化图标和地图颜色。

本文重点介绍MapBox默认的样式,样式相关的类和方法,以及如何动态更新样式并本地化语言。

MapBox样式对比

风格 常量 说明 v9 v11
Mapbox Standard STANDARD A dynamic and performant 3D style that is the default for Mapbox maps. - standard
Mapbox Standard Satellite STANDARD_SATELLITE Combines updated satellite imagery and vector layers to offer users improved clarity and detail. - standard-satellite
Mapbox Streets MAPBOX_STREETS A complete base map, perfect for incorporating your own data. streets-v11 streets-v12
Outdoors OUTDOORS A general-purpose style tailored to outdoor activities. outdoors-v11 outdoors-v12
Light LIGHT Subtle light backdrop for data visualizations. light-v10 light-v11
Dark DARK Subtle dark backdrop for data visualizations. dark-v10 dark-v11
Satellite SATELLITE A beautiful global satellite and aerial imagery layer. satellite-v9 satellite-v9
Satellite Streets SATELLITE_STREETS Global satellite and aerial imagery with unobtrusive labels. satellite-streets-v11 satellite-streets-v12
Traffic Day TRAFFIC_DAY Color-coded roads based on live traffic congestion data. traffic-day-v2 traffic-day-v2
Traffic Night TRAFFIC_NIGHT Color-coded roads based on live traffic congestion data, designed to maximize legibility in low-light situations. traffic-night-v2 traffic-night-v2

主要类和方法

Style类

Style对象是指应用程序中使用的Mapbox地图样式。

classDiagram
    MapboxStyleManager <|-- Style

    class MapboxStyleManager{
        +StyleManager styleManager
    }
    class Style {
    }

Style类

class Style internal constructor(
  styleManager: StyleManager,
  pixelRatio: Float,
  mapLoadingErrorDelegate: MapLoadingErrorDelegate,
) : MapboxStyleManager(styleManager, pixelRatio, mapLoadingErrorDelegate) {

  @Volatile
  private var isStyleValid = true
  
  /**
   * Returns the existing style layers.
   *
   * @return The list containing the ids of the existing style layers.
   */
  override val styleLayers: List<StyleObjectInfo>
    @MainThread
    get() {
      checkNativeStyle("getStyleLayers")
      return super.styleLayers
    }
    ...
}
  • MapboxStyleManager 类
open class MapboxStyleManager @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX) constructor(
  /**
   * Native style manager instance.
   */
  @get:RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX)
  val styleManager: StyleManager,
  /**
   * Current pixel ratio.
   */
  val pixelRatio: Float,
  /**
   * For internal usage.
   */
  @get:RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX)
  val mapLoadingErrorDelegate: MapLoadingErrorDelegate,
) {
  }
  ...
}
  • StyleManager 类
public class StyleManager extends Observable {
    @MainThread
    public native boolean isStyleLoaded();

    @MainThread
    public native boolean styleLayerExists(@NonNull String layerId);

    @NonNull
    @MainThread
    public native List<StyleObjectInfo> getStyleLayers();
    ...
}

默认的MapBox样式

const val STANDARD = "mapbox://styles/mapbox/standard"
const val STANDARD_SATELLITE = "mapbox://styles/mapbox/standard-satellite"
const val MAPBOX_STREETS = "mapbox://styles/mapbox/streets-v12"
const val OUTDOORS = "mapbox://styles/mapbox/outdoors-v12"
const val LIGHT = "mapbox://styles/mapbox/light-v11"
const val DARK = "mapbox://styles/mapbox/dark-v11"
const val SATELLITE = "mapbox://styles/mapbox/satellite-v9"
const val SATELLITE_STREETS = "mapbox://styles/mapbox/satellite-streets-v12"
const val TRAFFIC_DAY = "mapbox://styles/mapbox/traffic-day-v2"
const val TRAFFIC_NIGHT = "mapbox://styles/mapbox/traffic-night-v2"

OnStyleLoaded 接口

/**
 * Callback to be invoked when a style has finished loading.
 */
fun interface OnStyleLoaded {
  /**
   * Invoked when a style has finished loading.
   *
   * @param style the style that has finished loading
   */
  fun onStyleLoaded(style: Style)
}

MapboxMap类

获取样式

var style: Style? = null
  @JvmSynthetic
  internal set
  get() {
    checkNativeMap("getStyle")
    return field
  }

设置样式

@JvmOverloads
fun loadStyle(
  style: String,
  onStyleLoaded: Style.OnStyleLoaded? = null,
) {
  checkNativeMap("loadStyle")
  initializeStyleLoad(
    onStyleLoaded,
    styleDataStyleLoadedListener = {},
  )
  applyStyle(style)
}

private fun applyStyle(style: String) {
  if (style.isValidUri()) {
    nativeMap.setStyleURI(style)
  } else {
    nativeMap.setStyleJSON(style.ifBlank { "{}" })
  }
}

本地化扩展

com.mapbox.maps.extension.localization包中实现了本地化功能,这种方法不支持standard样式。主要实现代码如下:

@JvmOverloads
fun MapboxStyleManager.localizeLabels(locale: Locale, layerIds: List<String>? = null) {
  if (styleURI == "mapbox://styles/mapbox/standard") {
    throw RuntimeException(
      "Mapbox Standard style does not support client-side runtime localization." +
        " Consider using Mapbox internationalization capability instead: https://www.mapbox.com/blog/maps-internationalization-34-languages"
    )
  }
  setMapLanguage(locale, this, layerIds)
}

internal fun setMapLanguage(locale: Locale, style: MapboxStyleManager, layerIds: List<String>?) {
  val convertedLocale = "name_${locale.language}"
  if (!isSupportedLanguage(convertedLocale)) {
    logE(TAG, "Locale: $locale is not supported.")
    return
  }

  layerIds?.forEach { id ->
    localizeTextFieldExpression(
      style = style,
      layerId = id,
      locale = locale,
      convertedLocale = convertedLocale,
      filterSymbolLayers = true,
    )
  } ?: style.styleLayers.forEach { layer ->
    if (layer.type == SYMBOL) {
      localizeTextFieldExpression(
        style = style,
        layerId = layer.id,
        locale = locale,
        convertedLocale = convertedLocale,
        filterSymbolLayers = false,
      )
    }
  }
}

private fun localizeTextFieldExpression(
  style: MapboxStyleManager,
  layerId: String,
  locale: Locale,
  convertedLocale: String,
  filterSymbolLayers: Boolean,
) {
  if (filterSymbolLayers) {
    val type = style.getStyleLayerProperty(layerId, TYPE).value.contents as? String
    if (type != SYMBOL) {
      return
    }
  }
  val textFieldProperty = style.getStyleLayerProperty(layerId, TEXT_FIELD)
  if (textFieldProperty.kind != StylePropertyValueKind.EXPRESSION) {
    return
  }
  val textField = textFieldProperty.value.toJson()
  val adaptedLocale = adaptLocaleToV8orV7IfNeeded(
    style,
    style.getStyleLayerProperty(layerId, SOURCE).value.contents as? String ?: "",
    locale
  ) ?: convertedLocale
  val getExpression = get(adaptedLocale).toJson()
  val localizedTextFieldExpressionAsJson = textField.replace(
    EXPRESSION_REGEX,
    getExpression
  ).replace(EXPRESSION_ABBR_REGEX, getExpression)
  if (BuildConfig.DEBUG) {
    logI(TAG, "Localize layer with expression: $localizedTextFieldExpressionAsJson")
  }
  val expected = Value.fromJson(localizedTextFieldExpressionAsJson)
  expected.value?.let { value ->
    style.setStyleLayerProperty(
      layerId,
      TEXT_FIELD,
      value
    )
  } ?: run {
    logE(TAG, "An error ${expected.error} occurred when converting $localizedTextFieldExpressionAsJson to a Value!")
  }
}

示例代码

地图样式类

设置地图样式,样式加载完成后重新本地化地图语言。

package com.example.mapdemo

import com.mapbox.maps.MapboxMap
import com.mapbox.maps.Style
import com.mapbox.maps.extension.localization.localizeLabels
import java.util.Locale

class MapStyle(map: MapboxMap) {
    private var map = map

    fun changeStyle(style: String) {
        map.loadStyle(style) {
            var layers = it.styleLayers
            if (style != Style.STANDARD && style != Style.STANDARD_SATELLITE) {
                it.localizeLabels(Locale.CHINESE)
            }
        }
    }
}

界面布局

v11-0布局.png
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.mapbox.maps.MapView
        android:id="@+id/mapView"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintBottom_toTopOf="@id/bottomView"
        app:layout_constraintTop_toTopOf="parent"
        app:mapbox_cameraBearing="0.0"
        app:mapbox_cameraPitch="0.0"
        app:mapbox_cameraTargetLat="32.2857965"
        app:mapbox_cameraTargetLng="104.293174"
        app:mapbox_cameraZoom="2" />

    <HorizontalScrollView
        android:id="@+id/bottomView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/background_dark"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toBottomOf="@id/mapView">

        <RadioGroup
            android:id="@+id/RadioGroup"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal"
            android:orientation="horizontal"
            android:paddingHorizontal="10dp">

            <RadioButton
                android:id="@+id/standard"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:checked="false"
                android:onClick="setMapStyle"
                android:text="3D基础"
                android:textColor="@color/white"
                android:textStyle="bold" />

            <RadioButton
                android:id="@+id/standardSatellite"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:onClick="setMapStyle"
                android:text="3D影像"
                android:textColor="@color/white"
                android:textStyle="bold" />

            <RadioButton
                android:id="@+id/streets"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:checked="true"
                android:onClick="setMapStyle"
                android:text="基础"
                android:textColor="@color/white"
                android:textStyle="bold" />

            <RadioButton
                android:id="@+id/satellite"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:onClick="setMapStyle"
                android:text="影像"
                android:textColor="@color/white"
                android:textStyle="bold" />

            <RadioButton
                android:id="@+id/satelliteStreets"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:onClick="setMapStyle"
                android:text="影像标签"
                android:textColor="@color/white"
                android:textStyle="bold" />

            <RadioButton
                android:id="@+id/outdoors"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:onClick="setMapStyle"
                android:text="户外"
                android:textColor="@color/white"
                android:textStyle="bold" />

            <RadioButton
                android:id="@+id/light"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:checked="false"
                android:onClick="setMapStyle"
                android:text="浅"
                android:textColor="@color/white"
                android:textStyle="bold" />

            <RadioButton
                android:id="@+id/dark"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:checked="false"
                android:onClick="setMapStyle"
                android:text="深"
                android:textColor="@color/white"
                android:textStyle="bold" />

        </RadioGroup>
    </HorizontalScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>

控件响应事件

fun setMapStyle(view: View) {
    val checked = (view as RadioButton).isChecked
    if (!checked)
        return

    val id = view.getId()
    if (id == R.id.standard) {
        mapStyle.changeStyle(Style.STANDARD)
    } else if (id == R.id.standardSatellite) {
        mapStyle.changeStyle(Style.STANDARD_SATELLITE)
    } else if (id == R.id.streets) {
        mapStyle.changeStyle(Style.MAPBOX_STREETS)
    } else if (id == R.id.satellite) {
        mapStyle.changeStyle(Style.SATELLITE)
    } else if (id == R.id.satelliteStreets) {
        mapStyle.changeStyle(Style.SATELLITE_STREETS)
    } else if (id == R.id.outdoors) {
        mapStyle.changeStyle(Style.OUTDOORS)
    } else if (id == R.id.light) {
        mapStyle.changeStyle(Style.LIGHT)
    } else if (id == R.id.dark) {
        mapStyle.changeStyle(Style.DARK)
    }
}

运行效果图

3D基础 3D影像
v11-A-3D-1基础.png
v11-A-3D-2影像.png
基础 影像 影像+标签
v11-B-1基础.png
v11-B-2影像.png
v11-B-3影像标签.png
户外
v11-B-4户外.png
v11-B-5浅.png
v11-B-6深.png

附不同样式中的图层

查看地图样式的图层Z索引顺序和图层ID。

样式 图层
Mapbox Standard -
Mapbox Standard Satellite -
Mapbox Streets land, landcover, national-park, landuse, pitch-outline, waterway-shadow, water-shadow, waterway, water, water-depth, hillshade, land-structure-polygon, land-structure-line, aeroway-polygon, aeroway-line, building, building-underground, tunnel-minor-case, tunnel-street-case, tunnel-minor-link-case, tunnel-secondary-tertiary-case, tunnel-primary-case, tunnel-major-link-case, tunnel-motorway-trunk-case, tunnel-path, tunnel-steps, tunnel-pedestrian, tunnel-construction, tunnel-minor, tunnel-minor-link, tunnel-major-link, tunnel-street, tunnel-street-low, tunnel-secondary-tertiary, tunnel-primary, tunnel-motorway-trunk, tunnel-oneway-arrow-blue, tunnel-oneway-arrow-white, ferry, ferry-auto, road-pedestrian-polygon-fill, road-pedestrian-polygon-pattern, road-path-bg, road-steps-bg, road-pedestrian-case, road-path, road-steps, road-pedestrian, golf-hole-line, road-polygon, turning-feature-outline, road-minor-case, road-street-case, road-minor-link-case, road-secondary-tertiary-case, road-primary-case, road-major-link-case, road-motorway-trunk-case, turning-feature, road-construction, road-minor, road-minor-link, road-major-link, road-street, road-street-low, road-secondary-tertiary, road-primary, road-motorway-trunk, road-rail, road-rail-tracks, level-crossing, road-oneway-arrow-blue, road-oneway-arrow-white, crosswalks, bridge-path-bg, bridge-steps-bg, bridge-pedestrian-case, bridge-path, bridge-steps, bridge-pedestrian, bridge-minor-case, bridge-street-case, bridge-minor-link-case, bridge-secondary-tertiary-case, bridge-primary-case, bridge-major-link-case, bridge-motorway-trunk-case, bridge-construction, bridge-minor, bridge-minor-link, bridge-major-link, bridge-street, bridge-street-low, bridge-secondary-tertiary, bridge-primary, bridge-motorway-trunk, bridge-major-link-2-case, bridge-motorway-trunk-2-case, bridge-major-link-2, bridge-motorway-trunk-2, bridge-oneway-arrow-blue, bridge-oneway-arrow-white, bridge-rail, bridge-rail-tracks, aerialway, admin-1-boundary-bg, admin-0-boundary-bg, admin-1-boundary, admin-0-boundary, admin-0-boundary-disputed, building-entrance, building-number-label, block-number-label, road-label, road-intersection, road-number-shield, road-exit-shield, path-pedestrian-label, golf-hole-label, ferry-aerialway-label, waterway-label, natural-line-label, natural-point-label, water-line-label, water-point-label, poi-label, transit-label, airport-label, settlement-subdivision-label, settlement-minor-label, settlement-major-label, state-label, country-label, continent-label
Satellite background, satellite
Satellite Streets background, satellite, tunnel-minor-case, tunnel-street-case, tunnel-minor-link-case, tunnel-secondary-tertiary-case, tunnel-primary-case, tunnel-major-link-case, tunnel-motorway-trunk-case, tunnel-path, tunnel-steps, tunnel-pedestrian, tunnel-minor, tunnel-minor-link, tunnel-major-link, tunnel-street, tunnel-street-low, tunnel-secondary-tertiary, tunnel-primary, tunnel-motorway-trunk, road-path, road-steps, road-pedestrian, road-minor-case, road-street-case, road-minor-link-case, road-secondary-tertiary-case, road-primary-case, road-major-link-case, road-motorway-trunk-case, road-minor, road-minor-link, road-major-link, road-street, road-street-low, road-secondary-tertiary, road-primary, road-motorway-trunk, bridge-path, bridge-steps, bridge-pedestrian, bridge-minor-case, bridge-street-case, bridge-minor-link-case, bridge-secondary-tertiary-case, bridge-primary-case, bridge-major-link-case, bridge-motorway-trunk-case, bridge-minor, bridge-minor-link, bridge-major-link, bridge-street, bridge-street-low, bridge-secondary-tertiary, bridge-primary, bridge-motorway-trunk, bridge-major-link-2-case, bridge-motorway-trunk-2-case, bridge-major-link-2, bridge-motorway-trunk-2, aerialway, admin-1-boundary-bg, admin-0-boundary-bg, admin-1-boundary, admin-0-boundary, admin-0-boundary-disputed, road-label, road-intersection, road-number-shield, road-exit-shield, path-pedestrian-label, ferry-aerialway-label, waterway-label, natural-line-label, natural-point-label, water-line-label, water-point-label, poi-label, transit-label, airport-label, settlement-subdivision-label, settlement-minor-label, settlement-major-label, state-label, country-label, continent-label
Outdoors land, landcover, national-park, national-park_tint-band, landuse, pitch-outline, waterway-shadow, water-shadow, waterway, water, water-depth, wetland, wetland-pattern, hillshade, contour-line, land-structure-polygon, land-structure-line, aeroway-polygon, aeroway-line, building, building-underground, tunnel-minor-case, tunnel-street-case, tunnel-minor-link-case, tunnel-secondary-tertiary-case, tunnel-primary-case, tunnel-major-link-case, tunnel-motorway-trunk-case, tunnel-path-trail, tunnel-path-cycleway-piste, tunnel-path, tunnel-steps, tunnel-pedestrian, tunnel-construction, tunnel-minor, tunnel-minor-link, tunnel-major-link, tunnel-street, tunnel-street-low, tunnel-secondary-tertiary, tunnel-primary, tunnel-motorway-trunk, tunnel-oneway-arrow-blue, tunnel-oneway-arrow-white, cliff, ferry, ferry-auto, road-pedestrian-polygon-fill, road-pedestrian-polygon-pattern, road-path-bg, road-steps-bg, road-pedestrian-case, road-path-trail, road-path-cycleway-piste, road-path, road-steps, road-pedestrian, golf-hole-line, road-polygon, turning-feature-outline, road-minor-case, road-street-case, road-minor-link-case, road-secondary-tertiary-case, road-primary-case, road-major-link-case, road-motorway-trunk-case, turning-feature, road-construction, road-minor, road-minor-link, road-major-link, road-street, road-street-low, road-secondary-tertiary, road-primary, road-motorway-trunk, road-rail, road-rail-tracks, level-crossing, road-oneway-arrow-blue, road-oneway-arrow-white, crosswalks, gate-fence-hedge, bridge-path-bg, bridge-steps-bg, bridge-pedestrian-case, bridge-path-trail, bridge-path-cycleway-piste, bridge-path, bridge-steps, bridge-pedestrian, gate-label, bridge-minor-case, bridge-street-case, bridge-minor-link-case, bridge-secondary-tertiary-case, bridge-primary-case, bridge-major-link-case, bridge-motorway-trunk-case, bridge-construction, bridge-minor, bridge-minor-link, bridge-major-link, bridge-street, bridge-street-low, bridge-secondary-tertiary, bridge-primary, bridge-motorway-trunk, bridge-major-link-2-case, bridge-motorway-trunk-2-case, bridge-major-link-2, bridge-motorway-trunk-2, bridge-oneway-arrow-blue, bridge-oneway-arrow-white, bridge-rail, bridge-rail-tracks, aerialway, admin-1-boundary-bg, admin-0-boundary-bg, admin-1-boundary, admin-0-boundary, admin-0-boundary-disputed, contour-label, building-entrance, building-number-label, block-number-label, road-label, road-intersection, road-number-shield, road-exit-shield, path-pedestrian-label, golf-hole-label, ferry-aerialway-label, waterway-label, natural-line-label, natural-point-label, water-line-label, water-point-label, poi-label, transit-label, airport-label, settlement-subdivision-label, settlement-minor-label, settlement-major-label, state-label, country-label, continent-label
Light land, national-park, landuse, waterway, water, land-structure-polygon, land-structure-line, aeroway-polygon, aeroway-line, building, tunnel-path-trail, tunnel-path-cycleway-piste, tunnel-path, tunnel-steps, tunnel-pedestrian, tunnel-simple, road-path-trail, road-path-cycleway-piste, road-path, road-steps, road-pedestrian, road-simple, road-rail, bridge-path-trail, bridge-path-cycleway-piste, bridge-path, bridge-steps, bridge-pedestrian, bridge-case-simple, bridge-simple, bridge-rail, admin-1-boundary-bg, admin-0-boundary-bg, admin-1-boundary, admin-0-boundary, admin-0-boundary-disputed, road-label-simple, waterway-label, natural-line-label, natural-point-label, water-line-label, water-point-label, poi-label, airport-label, settlement-subdivision-label, settlement-minor-label, settlement-major-label, state-label, country-label, continent-label
Dark land, national-park, landuse, waterway, water, land-structure-polygon, land-structure-line, aeroway-polygon, aeroway-line, building, tunnel-path-trail, tunnel-path-cycleway-piste, tunnel-path, tunnel-steps, tunnel-pedestrian, tunnel-simple, road-path-trail, road-path-cycleway-piste, road-path, road-steps, road-pedestrian, road-simple, road-rail, bridge-path-trail, bridge-path-cycleway-piste, bridge-path, bridge-steps, bridge-pedestrian, bridge-case-simple, bridge-simple, bridge-rail, admin-1-boundary-bg, admin-0-boundary-bg, admin-1-boundary, admin-0-boundary, admin-0-boundary-disputed, road-label-simple, waterway-label, natural-line-label, natural-point-label, water-line-label, water-point-label, poi-label, airport-label, settlement-subdivision-label, settlement-minor-label, settlement-major-label, state-label, country-label, continent-label
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,717评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,501评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,311评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,417评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,500评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,538评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,557评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,310评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,759评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,065评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,233评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,909评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,548评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,172评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,420评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,103评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,098评论 2 352

推荐阅读更多精彩内容