set コマンド構文
SET キー ID [フィールド名 値 ...] [EX 秒] [NX|XX] (OBJECT geojson )|(POINT lat lon z)|(BOUNDS minlat minlon maxlat maxlon)|(HASH geohash)|(STRING 値)
#set コマンドは、redis の # と同等です。 ##hash
コマンドの key
と id
の組み合わせでもありますが、違いは、Tile38 の set
コマンドは、より多くのその他の属性も保持できることです。 FIELD
フィールドのカスタマイズや EX
有効期間の設定など、この構文に役立つ java api## を設計する必要があります。開発者が Tile38 をより適切に使用できるようになります。
文法分析
SET
、このキーワードを別個の部分として扱います;2. 2 番目の部分は
key id [FIELD name value ...] [EX 秒] [NX| XX]
3. 3 番目の部分は、最終的なターゲット データ オブジェクトです:
(OBJECT geojson)|(POINT lat lon z) |(BOUNDS minlat minlon maxlat maxlon)|(HASH geohash)|(STRING 値)
1. コマンド キーワードの最初の部分は列挙によって管理します。 # #コード設計
enum Tile38Command implements ProtocolKeyword { SET; public final byte[] bytes; static final String UNDERSCORE = "_"; static final String SPACE = " "; Tile38Command() { String name = StringUtils.replace(this.name(), UNDERSCORE, SPACE); this.bytes = name.getBytes(StandardCharsets.US_ASCII); } @Override public byte[] getBytes() { return this.bytes; } }
Redis クライアント ツールは送信前にすべてのコマンドをエンコードする必要があるため、すべてのコマンドは
ProtocolKeywordインターフェイスを実装する必要があります。コマンドの開始キーワードが 2 つ以上の単語の場合は、それらをアンダースコアで接続します。バイトに変換する場合は、アンダースコアをスペースで置き換えることができます。
2. コマンドの 2 番目の部分を特定のクラスに抽象化し、関連フィールドを通じてそれを記述します: <pre class='brush:php;toolbar:false;'>public class SetOpts {
private String key;
private String id;
//字段值必须是双精度浮点型
private Map<String, Double> fields;
// 单位秒
private int ex;
// 创建方式:
// NX 不存在的时候创建
// XX 存在的时候更新
private NxXx nxXx;
private SetOpts(Builder builder) {
this.key = builder.key;
this.id = builder.id;
this.fields = builder.fields;
this.ex = builder.ex;
this.nxXx = builder.nxXx;
}
// 把所有的参数按顺序放到列表中
public List<String> commandLine() {
List<String> result = new LinkedList<>();
result.add(this.key);
result.add(this.id);
// 添加所有的FIELD
if (MapUtils.isNotEmpty(this.fields)) {
for (Map.Entry<String, Double> entry : this.fields.entrySet()) {
result.add("FIELD");
result.add(entry.getKey());
result.add(entry.getValue().toString());
}
}
// 添加`EX`
if (this.ex >= 0) {
result.add("EX");
result.add(String.valueOf(this.ex));
}
// 添加NX或XX
if (Objects.nonNull(this.nxXx)) {
result.add(this.nxXx.name());
}
// 返回结果
return result;
}
public enum NxXx {
NX,
XX
}
// 建造者模式
public static class Builder {
private String key;
private String id;
//字段值必须是双精度浮点型
private Map<String, Double> fields;
// 单位秒
private int ex = -1;
// 创建方式:
// NX 不存在的时候创建
// XX 存在的时候更新
private NxXx nxXx;
public Builder key(String key) {
this.key = key;
return this;
}
public Builder id(String id) {
this.id = id;
return this;
}
public Builder field(String field, double value) {
if (Objects.isNull(this.fields)) {
this.fields = new LinkedHashMap<>();
}
this.fields.put(field, value);
return this;
}
public Builder ex(int seconds) {
this.ex = seconds;
return this;
}
public Builder nxXx(NxXx nxXx) {
this.nxXx = nxXx;
return this;
}
public SetOpts build() throws AwesomeException {
if (StringUtils.isEmpty(this.key)) {
throw new AwesomeException(500, "key is empty");
}
if (StringUtils.isEmpty(this.id)) {
throw new AwesomeException(500, "id is empty");
}
// 创建SetOpts对象
return new SetOpts(this);
}
}
}</pre>
上記では、ビルダーの設計モードを使用してすべてのパラメータを配置します。 SetOpts クラスを使用すると、開発者は SetOpts オブジェクトの構築を通じてコマンド内のパラメーターを柔軟に制御できます。
3. 3 番目の部分のさまざまなデータ オブジェクトをさまざまなタイプに変換する必要があります:
POINT データ型
Point のキー フィールドは経度と緯度です。さらに、追加フィールド
zがあり、これは追加のビジネス パラメーターを保存するために使用され、空にすることができます。
public class Point extends Element implements Serializable { // 经度 private double lng; // 维度 private double lat; // 额外的数据 private double z; public Point(double lng, double lat, double z) { this.lat = lat; this.lng = lng; this.z = z; } public Point(double lng, double lat) { this(lng, lat, Integer.MIN_VALUE); } @Override public List<String> commandArgs() { List<String> result = new LinkedList<>(); result.add("POINT"); result.add(String.valueOf(this.lng)); result.add(String.valueOf(this.lat)); if (this.z != Integer.MIN_VALUE) { result.add(String.valueOf(this.z)); } return result; } }
BOUNDS データ型BOUNDS は長方形であり、そのキー フィールドは左下隅と右上隅です。左下隅と右上隅を表すには、座標 1 と座標 2 を使用します。 ;
@AllArgsConstructor public class Bounds extends Element { private double[] coordinate1; private double[] coordinate2; @Override public List<String> commandArgs() { List<String> result = new LinkedList<>(); result.add("BOUNDS"); result.add(String.valueOf(coordinate1[0])); result.add(String.valueOf(coordinate1[1])); result.add(String.valueOf(coordinate2[0])); result.add(String.valueOf(coordinate2[1])); return result; } }
HASH および STRING データ型
HASH と STRING は実際には別の文字列ですが、開発者が使用できるようにカプセル化しています;
@AllArgsConstructor public class Geohash extends Element { private String hash; @Override public List<String> commandArgs() { List<String> result = new LinkedList<>(); result.add("HASH"); result.add(this.hash); return result; } } @AllArgsConstructor public class RawString extends Element { private String raw; @Override public List<String> commandArgs() { List<String> result = new LinkedList<>(); result.add("STRING"); result.add(this.raw); return result; } }
OBJECT データ型
OBJECT は実際には GeoJSON データです。このタイプのデータは少し複雑です。全部で 6 つのタイプがあります。詳しく知りたい方は、ここを参照してください。 geojson.org/
Point, LineString, Polygon, MultiPoint, MultiLineString, MultiPolygon
In order forこれら 6 つのタイプをより効果的に使用するために、ビルダー パターンを使用して GeoJSON データ タイプも設計します。
@Data public class GeoJson { public static class Builder { public Point.Builder point() { return new Point.Builder(); } public MultiPoint.Builder multPoint() { return new MultiPoint.Builder(); } public LineString.Builder lineString() { return new LineString.Builder(); } public MultiLineString.Builder multiLineString() { return new MultiLineString.Builder(); } public Polygon.Builder polygon() { return new Polygon.Builder(); } public MultiPolygon.Builder multiPolygon() { return new MultiPolygon.Builder(); } } }
ここで、大きなクラスに複数のメソッドを作成し、各メソッドに対応するタイプのビルダーを配置します。この場合、これは、このクラスでオブジェクトを作成する方法が 6 つあることと同等であり、各ビルダーは対応するオブジェクトを構築することのみを担当します。
以下は 6 つのビルダーのコードです。各オブジェクトは最も基本的な BaseGeoJson に基づいて構築されています。パブリック フィールド タイプと追加のメタ フィールドは BaseGeoJson から抽出されます。各タイプの違いは座標にあります。ポイントの数やレベルが異なるため、それぞれのタイプの特性に応じて、次のようなコード設計になります。
// Point类型 public static class Point extends BaseGeoJson { // 坐标点 private double[] coordinates; Point(Builder builder) { super(builder); this.type = GeoJsonType.Point; this.coordinates = builder.coordinates; } @Override protected Object coordinates() { return this.coordinates; } public static class Builder extends BaseGeoJson.Builder { private double[] coordinates; public Builder coordinate(double lon, double lat) { coordinates = new double[]{lat, lon}; return this; } public Point build() { return new Point(this); } } } // MultiPoint类型 public static class MultiPoint extends BaseGeoJson { private double[][] coordinates; MultiPoint(Builder builder) { super(builder); this.type = GeoJsonType.MultiPoint; this.coordinates = builder.convert2Array(); } @Override protected Object coordinates() { return this.coordinates; } public static class Builder extends BaseGeoJson.Builder { private List<Coordinate> coordinates; public Builder coordinate(double lon, double lat) { if (CollectionUtils.isEmpty(this.coordinates)) { this.coordinates = new LinkedList<>(); } this.coordinates.add(new Coordinate(lat, lon)); return this; } protected double[][] convert2Array() { int length = this.coordinates.size(); double[][] result = new double[length][]; for (int i = 0; i < length; i++) { result[i] = this.coordinates.get(i).convertToArray(); } return result; } @Override public MultiPoint build() { return new MultiPoint(this); } } } // LineString类型 public static class LineString extends MultiPoint { private double[][] coordinates; LineString(Builder builder) { super(builder); this.type = GeoJsonType.LineString; } public static class Builder extends MultiPoint.Builder { @Override public LineString build() { return new LineString(this); } } } // MultiLineString类型 public static class MultiLineString extends BaseGeoJson { private double[][][] coordinates; MultiLineString(Builder builder) { super(builder); this.type = GeoJsonType.MultiLineString; this.coordinates = builder.convertToArray(); } @Override protected Object coordinates() { return this.coordinates; } public static class Builder extends BaseGeoJson.Builder { private List<Line> lines = new LinkedList<>(); public Line line() { return new Line(this); } void addLine(Line line) { lines.add(line); } double[][][] convertToArray() { int length = this.lines.size(); double[][][] result = new double[length][][]; for (int i = 0; i < length; i++) { Line line = this.lines.get(i); result[i] = line.convert2Array(); } return result; } @Override public BaseGeoJson build() { return new MultiLineString(this); } } static class Line { private List<Coordinate> coordinates; private Builder builder; Line(Builder builder) { this.builder = builder; this.builder.addLine(this); } private double[][] convert2Array() { int length = this.coordinates.size(); double[][] result = new double[length][]; for (int i = 0; i < length; i++) { result[i] = this.coordinates.get(i).convertToArray(); } return result; } public Line coordinate(double lon, double lat) { if (CollectionUtils.isEmpty(this.coordinates)) { this.coordinates = new LinkedList<>(); } this.coordinates.add(new Coordinate(lat, lon)); return this; } public Line nextLine() { return new Line(this.builder); } public Builder end() { return this.builder; } } } // Polygon类型 public static class Polygon extends MultiPoint { private double[][][] coordinates; Polygon(Builder builder) { super(builder); this.type = GeoJsonType.Polygon; this.coordinates = new double[][][]{builder.convert2Array()}; } public static class Builder extends MultiPoint.Builder { @Override public Polygon build() { return new Polygon(this); } } } // MultiPolygon类型 public static class MultiPolygon extends BaseGeoJson { private double[][][][] coordinates; MultiPolygon(Builder builder) { super(builder); this.type = GeoJsonType.MultiPolygon; this.coordinates = new double[][][][]{builder.convert2Array()}; } @Override protected Object coordinates() { return this.coordinates; } public static class Builder extends BaseGeoJson.Builder { private List<Polygon> polygons = new LinkedList<>(); @Override public BaseGeoJson build() { return new MultiPolygon(this); } void addPolygon(Polygon polygon) { polygons.add(polygon); } private double[][][] convert2Array() { int length = this.polygons.size(); double[][][] result = new double[length][][]; for (int i = 0; i < length; i++) { result[i] = this.polygons.get(i).convert2Array(); } return result; } } static class Polygon { private List<Coordinate> coordinates; private Builder builder; Polygon(Builder builder) { this.builder = builder; this.builder.addPolygon(this); } private double[][] convert2Array() { int length = this.coordinates.size(); double[][] result = new double[length][]; for (int i = 0; i < length; i++) { result[i] = this.coordinates.get(i).convertToArray(); } return result; } public Polygon coordinate(double lon, double lat) { if (CollectionUtils.isEmpty(this.coordinates)) { this.coordinates = new LinkedList<>(); } this.coordinates.add(new Coordinate(lat, lon)); return this; } public Polygon nextLine() { return new Polygon(this.builder); } public Builder end() { return this.builder; } } } // 基类BaseGeoJson public abstract static class BaseGeoJson extends Element { // 公共字段type protected GeoJsonType type; // 公共字段metadata private Map<String, String> metadata; BaseGeoJson(Builder builder) { this.metadata = builder.metadata; } protected abstract Object coordinates(); // 转换成命令参数 @Override public List<String> commandArgs() { List<String> result = new LinkedList<>(); result.add("OBJECT"); result.add(toJson()); return result; } // 提供统一的转json方法 protected String toJson() { Map<String, Object> map = new LinkedHashMap<>(); map.put("type", this.type); map.put("coordinates", coordinates()); if (!CollectionUtils.isEmpty(this.metadata)) { for (Map.Entry<String, String> entry : this.metadata.entrySet()) { map.put(entry.getKey(), entry.getValue()); } } return JsonUtil.obj2String(map); } abstract static class Builder { private Map<String, String> metadata; public Builder meta(String key, String value) { if (MapUtils.isEmpty(this.metadata)) { this.metadata = new LinkedHashMap<>(); } this.metadata.put(key, value); return this; } public abstract BaseGeoJson build(); } static class Coordinate { private double lat; private double lon; Coordinate(double lat, double lon) { this.lat = lat; this.lon = lon; } public double[] convertToArray() { return new double[]{this.lat, this.lon}; } } // GeoJSON所有的数据类型 enum GeoJsonType { Point, LineString, Polygon, MultiPoint, MultiLineString, MultiPolygon } }
最後に、基本クラスの要素を追加します。
public abstract class Element implements Serializable { public abstract List<String> commandArgs(); }
使い方
We All データ型は特定のコード設計に変換されます。使用方法を見てみましょう:
private String setElement(SetOpts setOpts, Element element) { List<String> args1 = setOpts.commandLine(); List<String> commandArgs = element.commandArgs(); return execute(Tile38Command.SET, args1, commandArgs); } /** * 设置点位 * * @param setOpts * @param point * @return */ public String setPoint(SetOpts setOpts, Point point) { return setElement(setOpts, point); } /** * 设置对象 * * @param setOpts * @param geoJson * @return */ public String setObject(SetOpts setOpts, GeoJson.BaseGeoJson geoJson) { return setElement(setOpts, geoJson); } /** * 设置矩形边界 * * @param setOpts * @param bounds * @return */ public String setBounds(SetOpts setOpts, Bounds bounds) { return setElement(setOpts, bounds); } /** * 设置geohash * * @param setOpts * @param geohash * @return */ public String setGeohash(SetOpts setOpts, Geohash geohash) { return setElement(setOpts, geohash); } /** * 设置String * * @param setOpts * @param string * @return */ public String setString(SetOpts setOpts, RawString string) { return setElement(setOpts, string); }
以上がSpringboot統合タイルクライアントのSetコマンドの実装方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

この記事では、Javaプロジェクト管理、自動化の構築、依存関係の解像度にMavenとGradleを使用して、アプローチと最適化戦略を比較して説明します。

この記事では、MavenやGradleなどのツールを使用して、適切なバージョン化と依存関係管理を使用して、カスタムJavaライブラリ(JARファイル)の作成と使用について説明します。

この記事では、カフェインとグアバキャッシュを使用してJavaでマルチレベルキャッシュを実装してアプリケーションのパフォーマンスを向上させています。セットアップ、統合、パフォーマンスの利点をカバーし、構成と立ち退きポリシー管理Best Pra

この記事では、キャッシュや怠zyなロードなどの高度な機能を備えたオブジェクトリレーショナルマッピングにJPAを使用することについて説明します。潜在的な落とし穴を強調しながら、パフォーマンスを最適化するためのセットアップ、エンティティマッピング、およびベストプラクティスをカバーしています。[159文字]

Javaのクラスロードには、ブートストラップ、拡張機能、およびアプリケーションクラスローダーを備えた階層システムを使用して、クラスの読み込み、リンク、および初期化が含まれます。親の委任モデルは、コアクラスが最初にロードされ、カスタムクラスのLOAに影響を与えることを保証します


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

Dreamweaver Mac版
ビジュアル Web 開発ツール

Safe Exam Browser
Safe Exam Browser は、オンライン試験を安全に受験するための安全なブラウザ環境です。このソフトウェアは、あらゆるコンピュータを安全なワークステーションに変えます。あらゆるユーティリティへのアクセスを制御し、学生が無許可のリソースを使用するのを防ぎます。

WebStorm Mac版
便利なJavaScript開発ツール

mPDF
mPDF は、UTF-8 でエンコードされた HTML から PDF ファイルを生成できる PHP ライブラリです。オリジナルの作者である Ian Back は、Web サイトから「オンザフライ」で PDF ファイルを出力し、さまざまな言語を処理するために mPDF を作成しました。 HTML2FPDF などのオリジナルのスクリプトよりも遅く、Unicode フォントを使用すると生成されるファイルが大きくなりますが、CSS スタイルなどをサポートし、多くの機能強化が施されています。 RTL (アラビア語とヘブライ語) や CJK (中国語、日本語、韓国語) を含むほぼすべての言語をサポートします。ネストされたブロックレベル要素 (P、DIV など) をサポートします。

DVWA
Damn Vulnerable Web App (DVWA) は、非常に脆弱な PHP/MySQL Web アプリケーションです。その主な目的は、セキュリティ専門家が法的環境でスキルとツールをテストするのに役立ち、Web 開発者が Web アプリケーションを保護するプロセスをより深く理解できるようにし、教師/生徒が教室環境で Web アプリケーションを教え/学習できるようにすることです。安全。 DVWA の目標は、シンプルでわかりやすいインターフェイスを通じて、さまざまな難易度で最も一般的な Web 脆弱性のいくつかを実践することです。このソフトウェアは、
