Arcgis地图常用操作
2016-04-28 13:23
567 查看
效果图
功能简介
这个页面用到了添加图层,添加覆盖物,覆盖物的事件处理,地图的旋转、缩放,高德定位,地图分层显隐,关键词搜索等功能。本篇博客仅为了记录相关功能实现的代码块,所以未进行排版梳理,对Arcgis有需求的,建议看官方文档 或中文文档 。
布局代码
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent"> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginBottom="50dp"> <include android:id="@+id/inc_head" layout="@layout/inc_common_headbar" /> <com.esri.android.map.MapView android:id="@+id/view_map" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_below="@id/inc_head" android:visibility="visible" /> <RelativeLayout android:layout_width="40dp" android:layout_height="40dp" android:layout_marginLeft="10dp" android:layout_marginTop="100dp" android:gravity="center" android:orientation="horizontal"> <com.sjkj.travel.view.SouthView android:layout_width="match_parent" android:layout_height="match_parent" /> <ImageView android:id="@+id/iv_south" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_margin="5dp" android:src="@drawable/ic_map_north" /> </RelativeLayout> <TextView android:id="@+id/tv_gps" android:layout_width="400dp" android:layout_height="400dp" android:background="@color/dark_green" android:visibility="invisible" /> <RadioGroup android:id="@+id/rg_type" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_marginRight="10dp" android:layout_marginTop="80dp" android:orientation="vertical"> <RadioButton android:id="@+id/rb_map_all" android:layout_width="35dp" android:layout_height="35dp" android:layout_marginTop="5dp" android:background="@drawable/selector_map_all" android:button="@null" android:checked="true" /> <RadioButton android:id="@+id/rb_map_point" android:layout_width="35dp" android:layout_height="35dp" android:layout_marginTop="5dp" android:background="@drawable/selector_map_point" android:button="@null" /> <RadioButton android:id="@+id/rb_map_wc" android:layout_width="35dp" android:layout_height="35dp" android:layout_marginTop="5dp" android:background="@drawable/selector_map_wc" android:button="@null" /> <RadioButton android:id="@+id/rb_map_store" android:layout_width="35dp" android:layout_height="35dp" android:layout_marginTop="5dp" android:background="@drawable/selector_map_store" android:button="@null" /> <RadioButton android:id="@+id/rb_map_door" android:layout_width="35dp" android:layout_height="35dp" android:layout_marginTop="5dp" android:background="@drawable/selector_map_door" android:button="@null" /> </RadioGroup> <Button android:id="@+id/bt_reset" android:layout_width="35dp" android:layout_height="35dp" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" android:layout_marginBottom="80dp" android:layout_marginRight="10dp" android:background="@drawable/ic_map_reset" /> <Button android:id="@+id/bt_locate" android:layout_width="35dp" android:layout_height="35dp" android:layout_above="@+id/bt_reset" android:layout_alignParentRight="true" android:layout_margin="10dp" android:background="@drawable/ic_map_locate" /> <LinearLayout android:id="@+id/ll_bottom" android:layout_width="match_parent" android:layout_height="70dp" android:layout_alignParentBottom="true" android:clickable="true" android:orientation="horizontal" android:visibility="gone"> <ImageView android:id="@+id/iv_info" android:layout_width="70dp" android:layout_height="match_parent" android:scaleType="centerCrop" android:src="@drawable/image_sample" /> <LinearLayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:background="@color/gray_bg" android:orientation="vertical" android:padding="5dp"> <TextView android:id="@+id/tv_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:textColor="@color/gray_deep" android:textSize="16sp" tools:text="情人树" /> <TextView android:id="@+id/tv_detail" android:layout_width="match_parent" android:layout_height="match_parent" android:ellipsize="end" android:gravity="left" android:maxLines="2" android:textColor="@color/gray_standard" android:textSize="14sp" tools:text="君不见黄河之水天上来,奔流到海不复还,衣带渐宽终不悔,为伊消得人憔悴,渔霸还休" /> </LinearLayout> <TextView android:layout_width="70dp" android:layout_height="match_parent" android:background="@color/food_monday" android:gravity="center" android:text="更多" android:textColor="@color/white" /> </LinearLayout> </RelativeLayout> </LinearLayout>
页面代码
public class MidFragment extends BaseFragment { private static final String TITLE = "中间"; private MapView mMapView;//地图 private Button mLocateBT, mResetBT;//定位、重置按钮 private RadioGroup mTypeRG; private double latitude = 30.343112;//当前点纬度 private double longitude = 120.11522;//当前点经度 private ImageView mSouthIV;//指南针 private SensorManager mSensorManager;//方向传感器 private GraphicsLayer mMyLayer;//当前位置的图层 private int mMyUID;//当前位置的图标ID private PictureMarkerSymbol mLocationSymbol;//当前位置的图标 private Callout mCallout;//地图弹窗 private ArcGISDynamicMapServiceLayer mServiceLayer; private String url = "http://192.168.1.235:6080/arcgis/rest/services/SanKeFolder/SanKe_0426/MapServer"; // private String url = "http://huangyi2016.iask.in:23527/arcgis/rest/services/SanKeFolder/SanKe_0426/MapServer"; // private String url = "http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer"; private Point mClickPoint;//地图点击点 private IdentifyParameters params = null;//搜索条件 private boolean isNavigation = false;//是否是导航模式 private boolean isRomation = false;//是否正在旋转 private float mMapDegree;//地图旋转角度 private float mSensorDegree;//传感器角度 private int WKID_IN = 4326;//输入坐标系 private int WKID_OUT = 4490;//输出坐标系 private String stringBuffer = "经纬度:\n"; private TextView gpsTextView; private EntScenicSpot mScenicSpot;//景点 private LinearLayout mBottomLL;//底部景点信息布局 private TextView mBottomNameTV, mBottomDetailTV;//景点名称,景点详情 private ImageView mBottomIV;//景点图片 private boolean isBottomShow;//是否显示底部景点信息 public static MidFragment getInstance() { return new MidFragment(); } @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { if (null == mView) { mView = inflater.inflate(R.layout.fragment_mid, null); } return super.onCreateView(inflater, container, savedInstanceState); } @Override protected void initView() { mSensorManager = (SensorManager) getActivity().getSystemService(Context.SENSOR_SERVICE); // 获得传感器管理器 mCommonHeaderBar.initHeaderStyle(CommonHeaderBar.HeaderStyle.MIDTV); mCommonHeaderBar.setMidText(TITLE); mMapView = (MapView) findViewById(R.id.view_map); mResetBT = (Button) findViewById(R.id.bt_reset); mLocateBT = (Button) findViewById(R.id.bt_locate); mSouthIV = (ImageView) findViewById(R.id.iv_south); mTypeRG = (RadioGroup) findViewById(R.id.rg_type); gpsTextView = (TextView) findViewById(R.id.tv_gps); mBottomLL = (LinearLayout) findViewById(R.id.ll_bottom); mBottomNameTV = (TextView) findViewById(R.id.tv_name); mBottomDetailTV = (TextView) findViewById(R.id.tv_detail); mBottomIV = (ImageView) findViewById(R.id.iv_info); mCallout = mMapView.getCallout();//通过MapView获取Callout实例对象 mCallout.setStyle(R.xml.mime_callout_style);//为Callout设置样式文件 mLocationSymbol = new PictureMarkerSymbol(getActivity().getResources().getDrawable(R.drawable.ic_map_arrow));//设置当前点的图标样式 } @Override protected void initData() { ArcGISRuntime.setClientId("9yNxBahuPiGPbsdi");//去水印 //获取到经纬度就设置,没有就设置默认的 latitude = SharePreferenceUtil.getInstance().getString("LATITUDE") == null ? 30 : Double.valueOf(SharePreferenceUtil.getInstance().getString("LATITUDE")); longitude = SharePreferenceUtil.getInstance().getString("LONGTIUDE") == null ? 120 : Double.valueOf(SharePreferenceUtil.getInstance().getString("LONGTIUDE")); Log.v("--->获取", longitude + "/" + latitude); Toast.makeText(getActivity(), longitude + "/" + latitude, Toast.LENGTH_LONG).show(); mServiceLayer = new ArcGISDynamicMapServiceLayer(url);//在线地图 mMapView.addLayer(mServiceLayer);//添加图层 mMapView.setAllowRotationByPinch(true); //是否允许使用Pinch方式旋转地图 mMapView.setMapBackground(getResources().getColor(R.color.white), getResources().getColor(R.color.white), 0, 0);//设置背景 //设置当前位置为中心点 Point wgsPoint = new Point(longitude, latitude); Point mapPoint = (Point) GeometryEngine.project(wgsPoint, SpatialReference.create(WKID_IN), SpatialReference.create(WKID_OUT)); mMapView.centerAt(mapPoint, true); Graphic graphic = new Graphic(mapPoint, mLocationSymbol); mMyLayer = new GraphicsLayer(); mMyUID = mMyLayer.addGraphic(graphic); mMapView.addLayer(mMyLayer);//添加覆盖物图层 // 限定当前显示区域 // Unit mapUnit = SpatialReference.create(3857).getUnit();//mMapView.getSpatialReference().getUnit(); // double zoomWidth = Unit.convertUnits(10, Unit.create(LinearUnit.Code.MILE_US), mapUnit); // Envelope zoomExtent = new Envelope(mapPoint, zoomWidth, zoomWidth); // mMapView.setExtent(zoomExtent); } @Override protected void initListener() { mMapView.setOnStatusChangedListener(new OnStatusChangedListener() {//地图的状态监听 @Override public void onStatusChanged(Object o, STATUS status) { if (status.equals(STATUS.INITIALIZED)) { //初始化完成才显示,防止黑屏 mMapView.postDelayed(new Runnable() { @Override public void run() { mMapView.setVisibility(View.VISIBLE); } }, 100); } } }); mResetBT.setOnClickListener(new View.OnClickListener() {//重置 @Override public void onClick(View v) { isNavigation = false;//关闭导航模式 mMapView.setRotationAngle(0); //初始化时地图角度,参数为正时按逆时针方向旋转 Point wgsPoint = new Point(longitude, latitude); Point mapPoint = (Point) GeometryEngine.project(wgsPoint, SpatialReference.create(WKID_IN), SpatialReference.create(WKID_OUT)); mMapView.centerAt(mapPoint, true); mSouthIV.setRotation(0); // gpsTextView.setVisibility(View.INVISIBLE); } }); mLocateBT.setOnClickListener(new View.OnClickListener() {//定位 @Override public void onClick(View v) { isNavigation = true;//启动导航模式 //当前位置图标的更新 Point wgsPoint = new Point(longitude, latitude); Point mapPoint = (Point) GeometryEngine.project(wgsPoint, SpatialReference.create(WKID_IN), SpatialReference.create(WKID_OUT)); mLocationSymbol.setAngle(0); mMapView.centerAt(mapPoint, true); Graphic graphic = new Graphic(mapPoint, mLocationSymbol); mMyLayer.updateGraphic(mMyUID, graphic); // gpsTextView.setVisibility(View.VISIBLE); // gpsTextView.setText(stringBuffer); } }); mMapView.setOnPinchListener(new OnPinchListener() {//地图旋转监听 @Override public void prePointersMove(float v, float v1, float v2, float v3, double v4) { } @Override public void postPointersMove(float v, float v1, float v2, float v3, double v4) { mSouthIV.post(new Runnable() { @Override public void run() { mMapDegree = (float) mMapView.getRotationAngle(); mSouthIV.setRotation(-mMapDegree); } }); } @Override public void prePointersDown(float v, float v1, float v2, float v3, double v4) { } @Override public void postPointersDown(float v, float v1, float v2, float v3, double v4) { isRomation = true; } @Override public void prePointersUp(float v, float v1, float v2, float v3, double v4) { } @Override public void postPointersUp(float v, float v1, float v2, float v3, double v4) { isRomation = false; } }); //高德定位监听 ToolGDLocate.initNewInstance(getActivity()); ToolGDLocate.startLocate(new ToolGDLocate.GDListener() { @Override public void onLocationChanged(AMapLocation amapLocation) { if (Math.abs(amapLocation.getLatitude() - latitude) > 0.00005 || Math.abs(amapLocation.getLongitude() - longitude) > 0.00005) { stringBuffer += (longitude + " - " + latitude + "\n"); } longitude = amapLocation.getLongitude(); latitude = amapLocation.getLatitude(); Point wgsPoint = new Point(longitude, latitude); Point mapPoint = (Point) GeometryEngine.project(wgsPoint, SpatialReference.create(WKID_IN), SpatialReference.create(WKID_OUT)); Graphic graphic = new Graphic(mapPoint, mLocationSymbol); mMyLayer.updateGraphic(mMyUID, graphic); Log.v("--->更新", longitude + "/" + latitude); } }); mMapView.setOnSingleTapListener(//覆盖物监听 new OnSingleTapListener() { @Override public void onSingleTap(float v, float v1) { if (!mMapView.isLoaded()) return; mCallout.hide(); View mView = LayoutInflater.from(getActivity()).inflate(R.layout.view_callout_locate, null);//弹出窗口布局文件对象 int[] graphicIDs = mMyLayer.getGraphicIDs(v, v1, 25); if (graphicIDs != null && graphicIDs.length > 0) { Graphic gr = mMyLayer.getGraphic(graphicIDs[0]); Point location = (Point) gr.getGeometry(); mCallout.setOffset(0, -15);//设置偏移量 mCallout.show(location, mView);//设置弹出窗显示的内容 } mClickPoint = mMapView.toMapPoint(v, v1); //关键词查询设置 String targetLayer = url.concat("/0"); // String[] queryArray = {targetLayer, "Name = '厕所'"}; String[] queryArray = {targetLayer, "Message like '%厕所%'"}; AsyncQueryTask ayncQuery = new AsyncQueryTask(); ayncQuery.execute(queryArray); //触碰点查询设置 params = new IdentifyParameters(); params.setTolerance(20); params.setDPI(98); // params.setLayers(new int[]{4}); params.setLayerMode(IdentifyParameters.ALL_LAYERS); params.setGeometry(mClickPoint); params.setSpatialReference(mMapView.getSpatialReference()); params.setMapHeight(mMapView.getHeight()); params.setMapWidth(mMapView.getWidth()); params.setReturnGeometry(true); // add the area of extent to identify parameters Envelope env = new Envelope(); mMapView.getExtent().queryEnvelope(env); params.setMapExtent(env); // execute the identify task off UI thread MyIdentifyTask mTask = new MyIdentifyTask(mClickPoint); mTask.execute(params); } } ); mTypeRG.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() { @Override public void onCheckedChanged(RadioGroup group, int checkedId) { switch (checkedId) { case R.id.rb_map_all: mServiceLayer.setVisible(true); break; case R.id.rb_map_point: mServiceLayer.setVisible(false); break; case R.id.rb_map_wc: ArcGISLayerInfo[] infos = mServiceLayer.getLayers(); infos[0].setVisible(true); mServiceLayer.refresh(); break; case R.id.rb_map_store: ArcGISLayerInfo[] infoss = mServiceLayer.getLayers(); infoss[0].setVisible(false); mServiceLayer.refresh(); break; case R.id.rb_map_door: break; } } }); mBottomLL.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(getActivity(), "跳转更多", Toast.LENGTH_SHORT).show(); } }); } //关键字查询 private class AsyncQueryTask extends AsyncTask<String, Void, FeatureResult> { @Override protected FeatureResult doInBackground(String... queryArray) { if (queryArray == null || queryArray.length <= 1) return null; String url = queryArray[0]; QueryParameters qParameters = new QueryParameters(); String whereClause = queryArray[1]; SpatialReference sr = SpatialReference.create(102100); // qParameters.setGeometry(mMapView.getExtent()); // qParameters.setGeometry(mClickPoint); qParameters.setOutSpatialReference(sr); qParameters.setReturnGeometry(true); qParameters.setWhere(whereClause); QueryTask qTask = new QueryTask(url); try { return qTask.execute(qParameters); } catch (Exception e) { e.printStackTrace(); } return null; } @Override protected void onPostExecute(FeatureResult results) { if (results != null) { // Toast.makeText(getActivity(), "您找到了一个厕所", Toast.LENGTH_SHORT).show(); for (Object element : results) { if (element instanceof Feature) { Feature feature = (Feature) element; Graphic graphic = new Graphic(feature.getGeometry(), feature.getSymbol(), feature.getAttributes()); // graphicsLayer.addGraphic(graphic); //结果添加事件 mCallout.hide(); View mView = LayoutInflater.from(getActivity()).inflate(R.layout.view_callout_locate, null);//弹出窗口布局文件对象 Point location = (Point) graphic.getGeometry(); mCallout.setOffset(0, -15);//设置偏移量 mCallout.show(location, mView);//设置弹出窗显示的内容 } } } } } //触碰点查询 private class MyIdentifyTask extends AsyncTask<IdentifyParameters, Void, IdentifyResult[]> { IdentifyTask task = new IdentifyTask(url); IdentifyResult[] M_Result; Point mAnchor; MyIdentifyTask(Point anchorPoint) { mAnchor = anchorPoint; } protected IdentifyResult[] doInBackground(IdentifyParameters... params) { if (params != null && params.length > 0) { IdentifyParameters mParams = params[0]; try { M_Result = task.execute(mParams); } catch (Exception e) { e.printStackTrace(); } } return M_Result; } @Override protected void onPostExecute(IdentifyResult[] results) { if (results != null && results.length > 0) { Log.v("-->", results[0].getDisplayFieldName()); mCallout.hide(); if (results[0].getAttributes().get("Name") != null && results[0].getAttributes().get("Name").equals("洗手间")) { View mView = LayoutInflater.from(getActivity()).inflate(R.layout.view_callout_locate, null);//弹出窗口布局文件对象 Geometry geometry = results[0].getGeometry(); mCallout.setOffset(0, -15);//设置偏移量 mCallout.show((Point) geometry, mView);//设置弹出窗显示的内容 } else if (results[0].getAttributes().get("SHAPE") != null && results[0].getAttributes().get("SHAPE").equals("点")) { if (results[0].getAttributes().get("Message") != null) getScenicSpot(results[0].getAttributes().get("Message").toString()); } else if (results[0].getAttributes().get("SHAPE") == null && isBottomShow) { showBottom(false); } else if (results[0].getAttributes().get("SHAPE") != null && !results[0].getAttributes().get("SHAPE").equals("点") && isBottomShow) { showBottom(false); } } else if (isBottomShow) { showBottom(false); } // ArrayList<IdentifyResult> resultList = new ArrayList<IdentifyResult>(); // // IdentifyResult result_1; // // for (int index = 0; index < results.length; index++) { // // result_1 = results[index]; // String displayFieldName = result_1.getDisplayFieldName(); // Map<String, Object> attr = result_1.getAttributes(); // for (String key : attr.keySet()) { // if (key.equalsIgnoreCase(displayFieldName)) { // resultList.add(result_1); // } // } // } } } @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { inflater.inflate(R.menu.menu_main, menu); } @Override public void onResume() { super.onResume(); mMapView.unpause(); mSensorManager.registerListener(sensorEventListener, mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION), SensorManager.SENSOR_DELAY_UI); } @Override public void onPause() { super.onPause(); mMapView.pause(); } @Override public void onStop() { super.onStop(); mSensorManager.unregisterListener(sensorEventListener); } /** * Tip: * ArcGISTiledMapServiceLayer类,这个类可以用来加载基础图层,但是默认是访问URL获取的,只要重写它的getTile()方法, * 在获取瓦片的时候先判断本地是否存在,如果本地不存在则使用super.getTile()方法获得URL中的相应瓦片,然后保存到本地。 */ private SensorEventListener sensorEventListener = new SensorEventListener() {//方向传感器监听 @Override public void onSensorChanged(final SensorEvent event) { if (event.sensor.getType() == Sensor.TYPE_ORIENTATION) { // 获取当前传感器获取到的角度 if (isNavigation && isRomation) {//记录手动旋转时传感器的角度 mSensorDegree = event.values[0]; } else if (isNavigation && !isRomation) {//旋转时调整地图角度 float degree = mMapDegree + event.values[0] - mSensorDegree; // Point centerPoint = (Point) GeometryEngine.project(new Point(longitude, latitude), SpatialReference.create(WKID_IN), SpatialReference.create(WKID_OUT)); // mMapView.centerAt(centerPoint, true);//设置中心点 mMapView.setRotationAngle(degree); mSouthIV.setRotation((float) -mMapView.getRotationAngle()); } else if (!isNavigation) { float degree = event.values[0]; //当前位置图标的更新 Point wgsPoint = new Point(longitude, latitude); Point mapPoint = (Point) GeometryEngine.project(wgsPoint, SpatialReference.create(WKID_IN), SpatialReference.create(WKID_OUT)); mLocationSymbol.setAngle(degree); Graphic graphic = new Graphic(mapPoint, mLocationSymbol); mMyLayer.updateGraphic(mMyUID, graphic); } } } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } }; //底部信息布局的显示/隐藏 private void showBottom(boolean toShow) { if (toShow) { //底部信息布局的显示 mBottomLL.setVisibility(View.VISIBLE); ObjectAnimator animation = ObjectAnimator.ofFloat(mBottomLL, "translationY", mBottomLL.getLayoutParams().height, 0); animation.setInterpolator(new DecelerateInterpolator()); animation.setDuration(300); animation.start(); isBottomShow = true; } else { //底部信息布局的隐藏 ObjectAnimator animation = ObjectAnimator.ofFloat(mBottomLL, "translationY", 0, mBottomLL.getLayoutParams().height); animation.setInterpolator(new DecelerateInterpolator()); animation.setDuration(300); animation.start(); isBottomShow = false; } } /** * 获取景点 */ private void getScenicSpot(final String id) { putAsyncTask(new AsyncTask<Void, Void, DataExchange>() { @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected DataExchange doInBackground(Void... params) { String strXML = HttpUtil.request(mXMLGenerator.getScenicSpotInfo(id)); DataExchange dataExg = mXMLResolver.getScenicSpotInfo(strXML); return dataExg; } @Override protected void onPostExecute(DataExchange result) { super.onPostExecute(result); dismissLoadingDialog(); if (result.isSuccess()) { List<EntScenicSpot> spots = (List<EntScenicSpot>) result.getBackData(); if (spots != null) { mScenicSpot = spots.get(0); mBottomNameTV.setText(mScenicSpot.getName()); mBottomDetailTV.setText(mScenicSpot.getDesc()); Glide.with(getActivity()).load(mScenicSpot.getPicpath()).into(mBottomIV); if (!isBottomShow) showBottom(true); } } else { if (!result.getErrorInfo().isEmpty()) showCustomToast(result.getErrorInfo()); else showCustomToast(R.string.individuality_dialog); } } }); } }
相关文章推荐
- ansible配置笔记(一)
- 《万物简史》中文版翻译质量低劣
- bootstrap弹出模态框滚动条问题
- Oracle 配置transparent gateway(透明网关)连接sqlserver数据库(gateway安装在sqlserver服务器)
- @Html.Partial,@Html.Action,@Html.RenderPartial,@Html.RenderAction [转]
- com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field 异常
- com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field 异常
- start_class core 具体执行了啥
- java删除指定目录及其文件
- 团队冲刺第一阶段个人工作总结10
- 条形码类型及常见条形码介绍
- 那些年,我们用来“躲避”杀毒软件的工具
- 27-Roman to Integer-Leetcode
- Wcf简单实例1
- 构建之法阅读笔记五
- 【Web动画】CSS3 3D 行星运转 && 浏览器渲染原理
- GraphicsMagick在centos环境的安装
- maven的setting配置
- php 随机读取一维数组的一个或多个元素
- 命令行修改root密码